Added a way to properly shut down the SCGI server.
authorFredrik Tolf <fredrik@dolda2000.com>
Sat, 11 Sep 2010 17:26:28 +0000 (19:26 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Sat, 11 Sep 2010 17:26:28 +0000 (19:26 +0200)
src/dolda/jsvc/scgi/DirServer.java
src/dolda/jsvc/scgi/Server.java

index 8f19d8a..d238504 100644 (file)
@@ -51,6 +51,17 @@ public class DirServer extends Server {
        RequestThread w = ctx.tg.respond(req);
        w.start();
     }
+    
+    protected void shutdown() {
+       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();
+           }
+       }
+    }
 
     private static void usage(PrintStream out) {
        out.println("usage: dolda.jsvc.scgi.DirServer [-h] [-e CHARSET] [-d DATADIR] PORT");
index f01eae9..f8d4637 100644 (file)
@@ -8,6 +8,7 @@ import java.util.*;
 public abstract class Server implements Runnable {
     private final ServerSocket sk;
     private final Logger logger = Logger.getLogger("dolda.jsvc.scgi");
+    private boolean running = false;
     public String headcs = "UTF-8";
     
     public Server(ServerSocket sk) {
@@ -97,7 +98,12 @@ public abstract class Server implements Runnable {
     public void run() {
        try {
            try {
-               while(true) {
+               synchronized(this) {
+                   if(running)
+                       throw(new IllegalStateException("SCGI server is already running"));
+                   running = true;
+               }
+               while(running) {
                    Socket nsk = sk.accept();
                    serve(nsk);
                }
@@ -105,7 +111,26 @@ public abstract class Server implements Runnable {
                sk.close();
            }
        } catch(IOException e) {
-           logger.log(Level.SEVERE, "SCGI server encountered I/O error", e);
+           if((e instanceof SocketException) && !running) {
+               /* Assume that stop() has closed the socket. */
+           } else {
+               logger.log(Level.SEVERE, "SCGI server encountered I/O error", e);
+           }
+       } finally {
+           shutdown();
+           running = false;
        }
     }
+    
+    public void stop() {
+       try {
+           running = false;
+           sk.close();
+       } catch(IOException e) {
+           throw(new RuntimeException(e));
+       }
+    }
+    
+    protected void shutdown() {
+    }
 }