X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fdolda%2Fjsvc%2FThreadContext.java;h=486bc91bb268fa5d7e1d5af06d569fd0c48dad00;hb=ed8f7296bfb39fbd66b79a113d4a72c6ade71fc0;hp=f21d04ccb9f6221c9a4af564c325ce55ea453b0c;hpb=c9837b5e87402fa1375fe6d3dd80cb3405edda42;p=jsvc.git diff --git a/src/dolda/jsvc/ThreadContext.java b/src/dolda/jsvc/ThreadContext.java index f21d04c..486bc91 100644 --- a/src/dolda/jsvc/ThreadContext.java +++ b/src/dolda/jsvc/ThreadContext.java @@ -7,10 +7,12 @@ public class ThreadContext extends ThreadGroup { private Logger logger = Logger.getLogger("dolda.jsvc.context"); private ThreadGroup workers; private long reqs = 0; + private final ServerContext ctx; public final Responder root; - public ThreadContext(ThreadGroup parent, String name, Class bootclass) { + public ThreadContext(ThreadGroup parent, String name, ServerContext ctx, Class bootclass) { super((parent == null)?(Thread.currentThread().getThreadGroup()):parent, name); + this.ctx = ctx; workers = new ThreadGroup(this, "Worker threads") { public void uncaughtException(Thread t, Throwable e) { logger.log(Level.SEVERE, "Worker thread terminated with an uncaught exception", e); @@ -23,10 +25,30 @@ public class ThreadContext extends ThreadGroup { logger.log(Level.SEVERE, "Service thread " + t.toString() + " terminated with an uncaught exception", e); } + public ServerContext server() { + return(ctx); + } + public void shutdown() { - interrupt(); if(root instanceof ContextResponder) ((ContextResponder)root).destroy(); + try { + long last = 0; + while(true) { + long now = System.currentTimeMillis(); + if(now - last > 10000) { + interrupt(); + last = now; + } + Thread[] th = new Thread[1]; + if(enumerate(th) < 1) + break; + th[0].join(10000); + } + } catch(InterruptedException e) { + logger.log(Level.WARNING, "Interrupted while trying to shut down all service threads. Some may remain.", e); + } + destroy(); } public RequestThread respond(Request req) { @@ -64,12 +86,23 @@ public class ThreadContext extends ThreadGroup { boot.interrupt(); Thread.currentThread().interrupt(); } - if(err[0] != null) + if(err[0] != null) { + destroy(); throw(new RuntimeException(err[0])); + } if(res[0] == null) { + destroy(); logger.log(Level.SEVERE, "No responder returned in spite of no error having happened."); throw(new NullPointerException("No responder returned in spite of no error having happened.")); } return(res[0]); } + + public static ThreadContext current() { + for(ThreadGroup tg = Thread.currentThread().getThreadGroup(); tg != null; tg = tg.getParent()) { + if(tg instanceof ThreadContext) + return((ThreadContext)tg); + } + return(null); + } }