diff options
author | Dwayne Boone <dwayne@zeroc.com> | 2005-09-15 15:59:45 +0000 |
---|---|---|
committer | Dwayne Boone <dwayne@zeroc.com> | 2005-09-15 15:59:45 +0000 |
commit | 6031428fc4dee2164e31cd18ed10084f827bf893 (patch) | |
tree | b1033bb3a77fef09925644655473677922ac3909 /java/src/Ice/Application.java | |
parent | Fixed copy/paste on tree (diff) | |
download | ice-6031428fc4dee2164e31cd18ed10084f827bf893.tar.bz2 ice-6031428fc4dee2164e31cd18ed10084f827bf893.tar.xz ice-6031428fc4dee2164e31cd18ed10084f827bf893.zip |
Bug 424 - fix potential double destroy
Diffstat (limited to 'java/src/Ice/Application.java')
-rw-r--r-- | java/src/Ice/Application.java | 256 |
1 files changed, 164 insertions, 92 deletions
diff --git a/java/src/Ice/Application.java b/java/src/Ice/Application.java index 55100afb3c1..1460cb91b8b 100644 --- a/java/src/Ice/Application.java +++ b/java/src/Ice/Application.java @@ -14,6 +14,8 @@ public abstract class Application public Application() { + _callbackInProgress = false; + _destroyed = false; _interrupted = false; } @@ -78,6 +80,34 @@ public abstract class Application status = 1; } + defaultInterrupt(); + + synchronized(_mutex) + { + while(_callbackInProgress) + { + try + { + _mutex.wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + if(_destroyed) + { + _communicator = null; + } + else + { + _destroyed = true; + // + // And _communicator != null, meaning will be destroyed next, + // _destroyed = true also ensures that any remaining callback won't do anything + // + } + } + if(_communicator != null) { try @@ -99,7 +129,7 @@ public abstract class Application _communicator = null; } - synchronized(this) + synchronized(_mutex) { if(_destroyHook != null) { @@ -141,136 +171,171 @@ public abstract class Application return _communicator; } - synchronized public static void + public static void destroyOnInterrupt() { - // - // Remove the shutdown hook it's set. - // - if(_shutdownHook != null) - { - try - { - Runtime.getRuntime().removeShutdownHook(_shutdownHook); - _shutdownHook = null; - } - catch(java.lang.IllegalStateException ex) - { - // - // Expected if we are in the process of shutting down. - // - } - } - - if(_destroyHook == null) + synchronized(_mutex) { // - // As soon as the destroy hook ends all the threads are - // terminated. So the destroy hook will join the current - // thread before to end. + // Remove the shutdown hook it's set. // - _destroyHook = new DestroyHook(); - try + if(_shutdownHook != null) { - Runtime.getRuntime().addShutdownHook(_destroyHook); + try + { + Runtime.getRuntime().removeShutdownHook(_shutdownHook); + _shutdownHook = null; + } + catch(java.lang.IllegalStateException ex) + { + // + // Expected if we are in the process of shutting down. + // + } } - catch(java.lang.IllegalStateException ex) + + if(_destroyHook == null) { - if(_communicator != null) - { - _communicator.destroy(); - } + // + // As soon as the destroy hook ends all the threads are + // terminated. So the destroy hook will join the current + // thread before to end. + // + _destroyHook = new DestroyHook(); + try + { + Runtime.getRuntime().addShutdownHook(_destroyHook); + } + catch(java.lang.IllegalStateException ex) + { + if(_communicator != null) + { + _communicator.destroy(); + } + } } } } - synchronized public static void + public static void shutdownOnInterrupt() { - // - // Remove the destroy hook if it's set. - // - if(_destroyHook != null) - { - try - { - Runtime.getRuntime().removeShutdownHook(_destroyHook); - _destroyHook = null; - } - catch(java.lang.IllegalStateException ex) - { - // - // Expected if we are in the process of shutting down. - // - } - } - - if(_shutdownHook == null) + synchronized(_mutex) { // - // As soon as the shutdown hook ends all the threads are - // terminated. So the shutdown hook will join the current - // thread before to end. + // Remove the destroy hook if it's set. // - _shutdownHook = new ShutdownHook(); - try + if(_destroyHook != null) { - Runtime.getRuntime().addShutdownHook(_shutdownHook); + try + { + Runtime.getRuntime().removeShutdownHook(_destroyHook); + _destroyHook = null; + } + catch(java.lang.IllegalStateException ex) + { + // + // Expected if we are in the process of shutting down. + // + } } - catch(java.lang.IllegalStateException ex) + + if(_shutdownHook == null) { - if(_communicator != null) - { - _communicator.shutdown(); - } + // + // As soon as the shutdown hook ends all the threads are + // terminated. So the shutdown hook will join the current + // thread before to end. + // + _shutdownHook = new ShutdownHook(); + try + { + Runtime.getRuntime().addShutdownHook(_shutdownHook); + } + catch(java.lang.IllegalStateException ex) + { + if(_communicator != null) + { + _communicator.shutdown(); + } + } } } } - synchronized public static void + public static void defaultInterrupt() { - if(_shutdownHook != null) + synchronized(_mutex) { - try + if(_shutdownHook != null) { - Runtime.getRuntime().removeShutdownHook(_shutdownHook); - _shutdownHook = null; + try + { + Runtime.getRuntime().removeShutdownHook(_shutdownHook); + _shutdownHook = null; + } + catch(java.lang.IllegalStateException ex) + { + // + // Expected if we are in the process of shutting down. + // + } } - catch(java.lang.IllegalStateException ex) + + if(_destroyHook != null) { - // - // Expected if we are in the process of shutting down. - // + try + { + Runtime.getRuntime().removeShutdownHook(_destroyHook); + _destroyHook = null; + } + catch(java.lang.IllegalStateException ex) + { + // + // Expected if we are in the process of shutting down. + // + } } } + } - if(_destroyHook != null) + public static boolean + interrupted() + { + synchronized(_mutex) { - try - { - Runtime.getRuntime().removeShutdownHook(_destroyHook); - _destroyHook = null; - } - catch(java.lang.IllegalStateException ex) - { - // - // Expected if we are in the process of shutting down. - // - } + return _interrupted; } } - synchronized public static boolean - interrupted() + private static boolean + setCallbackInProgress(boolean destroy) { - return _interrupted; + synchronized(_mutex) + { + if(_destroyed) + { + // + // Being destroyed by main thread + // + return false; + } + _callbackInProgress = true; + _destroyed = destroy; + _interrupted = true; + return true; + } } - synchronized private static void - setInterrupt() + private static void + clearCallbackInProgress() { - _interrupted = true; + synchronized(_mutex) + { + _callbackInProgress = false; + _mutex.notify(); + } } static class DestroyHook extends Thread @@ -285,7 +350,7 @@ public abstract class Application { synchronized(_doneMutex) { - setInterrupt(); + setCallbackInProgress(true); Communicator communicator = communicator(); if(communicator != null) @@ -293,6 +358,8 @@ public abstract class Application communicator.destroy(); } + clearCallbackInProgress(); + while(!_done) { try @@ -332,7 +399,7 @@ public abstract class Application { synchronized(_doneMutex) { - setInterrupt(); + setCallbackInProgress(false); Communicator communicator = communicator(); if(communicator != null) @@ -340,6 +407,8 @@ public abstract class Application communicator.shutdown(); } + clearCallbackInProgress(); + while(!_done) { try @@ -371,5 +440,8 @@ public abstract class Application private static Communicator _communicator; private static DestroyHook _destroyHook; private static ShutdownHook _shutdownHook; + private static java.lang.Object _mutex = new java.lang.Object(); + private static boolean _callbackInProgress; + private static boolean _destroyed; private static boolean _interrupted; } |