Added some JMX support.
[jsvc.git] / src / dolda / jsvc / scgi / DirServer.java
index bd8d43c..5d82739 100644 (file)
@@ -7,15 +7,18 @@ import java.util.logging.*;
 import dolda.jsvc.*;
 import dolda.jsvc.util.*;
 import dolda.jsvc.j2ee.PosixArgs;
+import java.lang.management.ManagementFactory;
+import javax.management.*;
 
 public class DirServer extends Server {
     private final Map<File, DSContext> contexts = new HashMap<File, DSContext>();
-    private final File datroot;
+    public final Environment env;
     private final Logger logger = Logger.getLogger("dolda.jsvc.scgi.dirserver");
+    private Thread sdhook = null, main = null;
     
-    public DirServer(ServerSocket sk, File datroot) {
+    public DirServer(ServerSocket sk, Environment env) {
        super(sk);
-       this.datroot = datroot;
+       this.env = env;
     }
 
     private DSContext context(File file) throws ThreadContext.CreateException {
@@ -24,14 +27,25 @@ public class DirServer extends Server {
            String act = "loaded %s as %s";
            if(ctx != null) {
                if(ctx.mtime < file.lastModified()) {
-                   ctx.tg.destroy();
+                   ctx.tg.shutdown();
+                   try {
+                       ManagementFactory.getPlatformMBeanServer().unregisterMBean(ctx.mbean.name);
+                   } catch(InstanceNotFoundException e) {
+                   } catch(MBeanRegistrationException e) {
+                   }
                    contexts.remove(file);
                    ctx = null;
                    act = "reloaded %s as %s";
                }
            }
            if(ctx == null) {
-               ctx = new DSContext(file, datroot);
+               ctx = new DSContext(file, env);
+               try {
+                   ManagementFactory.getPlatformMBeanServer().registerMBean(ctx.mbean, ctx.mbean.name);
+               } catch(InstanceAlreadyExistsException e) {
+               } catch(MBeanRegistrationException e) {
+               } catch(NotCompliantMBeanException e) {
+               }
                contexts.put(file, ctx);
                logger.config(String.format(act, file, ctx.name()));
            }
@@ -51,6 +65,37 @@ public class DirServer extends Server {
        RequestThread w = ctx.tg.respond(req);
        w.start();
     }
+    
+    private class ShutdownHandler extends Thread {
+       public void run() {
+           sdhook = null;
+           DirServer.this.stop();
+           try {
+               main.join();
+           } catch(InterruptedException e) {}
+       }
+    }
+
+    protected void shutdown() {
+       try {
+           if(sdhook != null)
+               Runtime.getRuntime().removeShutdownHook(sdhook);
+       } catch(Exception e) {}
+       synchronized(contexts) {
+           for(Iterator<Map.Entry<File, DSContext>> i = contexts.entrySet().iterator(); i.hasNext();) {
+               Map.Entry<File, DSContext> e = i.next();
+               DSContext ctx = e.getValue();
+               i.remove();
+               ctx.tg.shutdown();
+           }
+       }
+       super.shutdown();
+       try {
+           ManagementFactory.getPlatformMBeanServer().unregisterMBean(dolda.jsvc.scgi.jmx.Server.name);
+       } catch(InstanceNotFoundException e) {
+       } catch(MBeanRegistrationException e) {
+       }
+    }
 
     private static void usage(PrintStream out) {
        out.println("usage: dolda.jsvc.scgi.DirServer [-h] [-e CHARSET] [-d DATADIR] PORT");
@@ -85,11 +130,8 @@ public class DirServer extends Server {
            usage(System.err);
            System.exit(1);
        }
-       if(datroot == null) {
-           datroot = new File(System.getProperty("user.home"), ".jsvc");
-           if(!datroot.exists() || !datroot.isDirectory())
-               datroot = null;
-       }
+       Environment env = (datroot == null)?new Environment():new Environment(datroot);
+       env.initvm();
        int port = Integer.parseInt(opt.rest[0]);
        ServerSocket sk;
        try {
@@ -99,10 +141,18 @@ public class DirServer extends Server {
            System.exit(1);
            return; /* Because javac is stupid. :-/ */
        }
-       DirServer s = new DirServer(sk, datroot);
+       DirServer s = new DirServer(sk, env);
+       try {
+           ManagementFactory.getPlatformMBeanServer().registerMBean(new dolda.jsvc.scgi.jmx.Server(s), dolda.jsvc.scgi.jmx.Server.name);
+       } catch(InstanceAlreadyExistsException e) {
+       } catch(MBeanRegistrationException e) {
+       } catch(NotCompliantMBeanException e) {
+       }
        if(charset != null)
            s.headcs = charset;
        
-       new Thread(s, "SCGI server thread").start();
+       Runtime.getRuntime().addShutdownHook(s.sdhook = s.new ShutdownHandler());
+       s.main = new Thread(s, "SCGI server thread");
+       s.main.start();
     }
 }