summaryrefslogtreecommitdiff
path: root/java/src/Ice/Application.java
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2005-09-15 15:59:45 +0000
committerDwayne Boone <dwayne@zeroc.com>2005-09-15 15:59:45 +0000
commit6031428fc4dee2164e31cd18ed10084f827bf893 (patch)
treeb1033bb3a77fef09925644655473677922ac3909 /java/src/Ice/Application.java
parentFixed copy/paste on tree (diff)
downloadice-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.java256
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;
}