Made the server context a more useful concept.
[jsvc.git] / src / dolda / jsvc / ThreadContext.java
index f21d04c..2d9931e 100644 (file)
@@ -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) {
@@ -72,4 +94,12 @@ public class ThreadContext extends ThreadGroup {
        }
        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);
+    }
 }