[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Update to the signal handling patch



Hello,

Attached is an updated version of the patch I send to the users list
yesterday. I failed to remember that the shutdown hook gets executed during
JVM shutdown regardless of the reason for said shutdown. Hence, pressing "q"
at the server console resulted in the shutdown hook attempting to
shutdown() the Env a second time (harmless bug; NullPointerException
results). In addition, for some reason the JVM failed to terminate because
of this! The latter I cannot explain, since it should terminate even if an
exception is thrown in the hook handler.

Anyways; the updated version of the patch properly implements
co-ordination between the shutdown hook and the main server loop. It's not a
patch for the patched version, but a replacement for the original patch (the
old one hasn't been commited to CVS, so I figured it would be fine).

-- 
/ Peter Schuller, InfiDyne Technologies HB

PGP userID: 0x5584BD98 or 'Peter Schuller <peter.schuller@infidyne.com>'
Key retrival: Send an E-Mail to getpgpkey@scode.infidyne.com
E-Mail: peter.schuller@infidyne.com Web: http://scode.infidyne.com

Index: Server.java
===================================================================
RCS file: /raid/Repository/ozone/org/ozoneDB/core/Server.java,v
retrieving revision 1.42
diff -r1.42 Server.java
10a11
> import java.lang.reflect.*;
28a30
>     private static boolean stoppedBySignal = false;
92a95,99
> 	    /* This is a good place to set up our shutdown hook. Doing it
> 	     * earlier would case a NullPointerException in race conditions.
> 	     * Doing it now is fine in terms of preventing database corruption
> 	     * because request processing has no yet begun. */
> 	   setupShutdownHook();
151c158,163
<             env.shutdown(); 
---
> 	    if (stoppedBySignal == false) {
> 	       /* If we got stopped due to a signal, 
> 		* env.shutdown() has already been invoked
> 		* by the shutdown hook. */
>                env.shutdown(); 
> 	    }
154c166
<             if (env != null) {
---
>             if (env != null && stoppedBySignal == false) {
162c174,221
<     } 
---
>     }
>     
>     private static void setupShutdownHook() {
>         try {
>            /* We will now attempt to add the shutdown hook
> 	    * using reflection. If we're running in a VM that does
> 	    * not support shutdown hooks (i.e., pre-1.3), it will yield
> 	    * a NoSuchMethodException, which we quietly ignore. */
> 	   Class runtimeClass = Runtime.class;
>            Method hookMethod = runtimeClass.getMethod("addShutdownHook", new Class[]{Thread.class});
>            Runtime rt = Runtime.getRuntime();
> 	   hookMethod.invoke(rt, new Object[]{createShutdownHook()});
> 	   
> 	   System.out.println("Shutdown hook successfully added. Process kills are now handled.");
> 	} catch (NoSuchMethodException nsme) {
> 	   /* Pre-1.3 VM. */
> 	   System.out.println("Running on pre-1.3 VM; no shutdown hook added.");
> 	} catch (SecurityException se) {
> 	   /* Either a screwy setup, or permission deliberately denied. */
> 	   System.out.println("WARNING: Shutdown hook not added; permission denied.");
> 	} catch (InvocationTargetException ite) {
> 	   /* Runtime.addShutdownHook() failed */
> 	   Throwable te = ite.getTargetException();
> 	   System.out.println("WARNING: Shutdown hook addition failed: "
> 	      + te.getClass().getName() + ": " + te.getMessage());
> 	} catch (IllegalAccessException iae) {
> 	   /* The VM is FUBAR. */
> 	   System.out.println("WARNING: Runtime.addShutdownHook() not public? VM bug?");
> 	}
>     }
>    
>    /**
>     * Constructs and returns a Thread to be used as a shutdown hook. It
>     * invokes Env.shutdown().
>     */
>    private static Runnable createShutdownHook() {
>       return new Thread() {
> 	    public void run() {
> 	       if (env.shuttingdown == false) {
> 		  /* Synchronization is not necessary
> 		   for the following two variables. */
> 	          stoppedBySignal = true;
> 		  stop = true;
> 	          env.shutdown();
> 	       }
> 	    }
>          };
>    }