summaryrefslogtreecommitdiff
path: root/java/src/Ice/Application.java
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2006-12-22 18:52:53 +0000
committerMatthew Newhook <matthew@zeroc.com>2006-12-22 18:52:53 +0000
commit84d9f5c369fceccfa16401ed50783ed2ad209559 (patch)
tree689d30c8707629f1db8155edadb47ce1bce363ad /java/src/Ice/Application.java
parentAdded autoflushing of batches (diff)
downloadice-84d9f5c369fceccfa16401ed50783ed2ad209559.tar.bz2
ice-84d9f5c369fceccfa16401ed50783ed2ad209559.tar.xz
ice-84d9f5c369fceccfa16401ed50783ed2ad209559.zip
http://bugzilla.zeroc.com/bugzilla/show_bug.cgi?id=1391.
Diffstat (limited to 'java/src/Ice/Application.java')
-rw-r--r--java/src/Ice/Application.java271
1 files changed, 132 insertions, 139 deletions
diff --git a/java/src/Ice/Application.java b/java/src/Ice/Application.java
index 6735596e912..b27315becef 100644
--- a/java/src/Ice/Application.java
+++ b/java/src/Ice/Application.java
@@ -135,6 +135,7 @@ public abstract class Application
status = 1;
}
+ // This clears any set interrupt.
defaultInterrupt();
synchronized(_mutex)
@@ -149,6 +150,7 @@ public abstract class Application
{
}
}
+
if(_destroyed)
{
_communicator = null;
@@ -157,8 +159,9 @@ public abstract class Application
{
_destroyed = true;
//
- // And _communicator != null, meaning will be destroyed next,
- // _destroyed = true also ensures that any remaining callback won't do anything
+ // And _communicator != null, meaning will be
+ // destroyed next, _destroyed = true also ensures that
+ // any remaining callback won't do anything
//
}
}
@@ -186,14 +189,9 @@ public abstract class Application
synchronized(_mutex)
{
- if(_destroyHook != null)
- {
- _destroyHook.done();
- }
-
- if(_shutdownHook != null)
+ if(_appHook != null)
{
- _shutdownHook.done();
+ _appHook.done();
}
}
@@ -232,43 +230,20 @@ public abstract class Application
synchronized(_mutex)
{
//
- // Remove the shutdown hook it's set.
+ // As soon as the destroy hook ends all the threads are
+ // terminated. So the destroy hook will join the current
+ // thread before to end.
//
- if(_shutdownHook != null)
+ try
{
- try
- {
- Runtime.getRuntime().removeShutdownHook(_shutdownHook);
- _shutdownHook.done();
- _shutdownHook = null;
- }
- catch(java.lang.IllegalStateException ex)
- {
- //
- // Expected if we are in the process of shutting down.
- //
- }
+ changeHook(new DestroyHook());
}
-
- if(_destroyHook == null)
+ catch(java.lang.IllegalStateException ex)
{
- //
- // 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();
- }
- }
+ if(_communicator != null)
+ {
+ _communicator.destroy();
+ }
}
}
}
@@ -279,85 +254,54 @@ public abstract class Application
synchronized(_mutex)
{
//
- // Remove the destroy hook if it's set.
+ // As soon as the shutdown hook ends all the threads are
+ // terminated. So the shutdown hook will join the current
+ // thread before to end.
//
- if(_destroyHook != null)
+ try
{
- try
- {
- Runtime.getRuntime().removeShutdownHook(_destroyHook);
- _destroyHook.done();
- _destroyHook = null;
- }
- catch(java.lang.IllegalStateException ex)
- {
- //
- // Expected if we are in the process of shutting down.
- //
- }
+ changeHook(new ShutdownHook());
}
-
- if(_shutdownHook == null)
+ catch(java.lang.IllegalStateException ex)
{
- //
- // 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();
- }
- }
+ if(_communicator != null)
+ {
+ _communicator.shutdown();
+ }
}
}
}
-
+
+ //
+ // Install a custom shutdown hook. This hook is registered as a
+ // shutdown hook and should do whatever is necessary to terminate
+ // the application. Note that this runs as a shutdown hook so the
+ // code must obey the same rules as a shutdown hook (specifically
+ // don't call exit!). The shutdown and destroy shutdown interrupts
+ // are cleared. This hook is automatically unregistered after
+ // Application.run() returns.
+ //
public static void
- defaultInterrupt()
+ setInterruptHook(java.lang.Thread newHook) // Pun intended.
{
- synchronized(_mutex)
+ try
{
- if(_shutdownHook != null)
- {
- try
- {
- Runtime.getRuntime().removeShutdownHook(_shutdownHook);
- _shutdownHook.done();
- _shutdownHook = null;
- }
- catch(java.lang.IllegalStateException ex)
- {
- //
- // Expected if we are in the process of shutting down.
- //
- }
- }
-
- if(_destroyHook != null)
- {
- try
- {
- Runtime.getRuntime().removeShutdownHook(_destroyHook);
- _destroyHook.done();
- _destroyHook = null;
- }
- catch(java.lang.IllegalStateException ex)
- {
- //
- // Expected if we are in the process of shutting down.
- //
- }
- }
+ changeHook(new CustomHook(newHook));
+ }
+ catch(java.lang.IllegalStateException ex)
+ {
+ // Ignore.
}
}
+
+ //
+ // This clears any shutdown hooks including any custom hook.
+ //
+ public static void
+ defaultInterrupt()
+ {
+ changeHook(null);
+ }
public static boolean
interrupted()
@@ -368,6 +312,42 @@ public abstract class Application
}
}
+ private static void
+ changeHook(AppHook newHook)
+ {
+ synchronized(_mutex)
+ {
+ //
+ // Remove any existing shutdown hooks.
+ //
+ try
+ {
+ if(_appHook != null)
+ {
+ Runtime.getRuntime().removeShutdownHook(_appHook);
+ _appHook.done();
+ _appHook = null;
+ }
+ }
+ catch(java.lang.IllegalStateException ex)
+ {
+ //
+ // Expected if we are in the process of shutting down.
+ //
+ }
+
+ //
+ // Note that we let the IllegalStateException propogate
+ // out if necessary.
+ //
+ if(newHook != null)
+ {
+ Runtime.getRuntime().addShutdownHook(newHook);
+ _appHook = newHook;
+ }
+ }
+ }
+
private static boolean
setCallbackInProgress(boolean destroy)
{
@@ -397,13 +377,24 @@ public abstract class Application
}
}
- static class DestroyHook extends Thread
+ static class AppHook extends Thread
{
- DestroyHook()
+ void
+ done()
{
- _done = false;
+ synchronized(_doneMutex)
+ {
+ _done = true;
+ _doneMutex.notify();
+ }
}
+ protected boolean _done = false;
+ protected java.lang.Object _doneMutex = new java.lang.Object();
+ }
+
+ static class DestroyHook extends AppHook
+ {
public void
run()
{
@@ -434,28 +425,10 @@ public abstract class Application
}
}
}
-
- void
- done()
- {
- synchronized(_doneMutex)
- {
- _done = true;
- _doneMutex.notify();
- }
- }
-
- private boolean _done;
- private java.lang.Object _doneMutex = new java.lang.Object();
}
- static class ShutdownHook extends Thread
+ static class ShutdownHook extends AppHook
{
- ShutdownHook()
- {
- _done = false;
- }
-
public void
run()
{
@@ -486,25 +459,45 @@ public abstract class Application
}
}
}
+ }
- void
- done()
+ // Although this class doesn't actually use any of the AppHook
+ // done stuff, its more trouble than its worth to add all of the
+ // code necessary to support another hook member variable and
+ // support code.
+ static class CustomHook extends AppHook
+ {
+ CustomHook(Thread hook)
+ {
+ _hook = hook;
+ }
+
+ public void
+ run()
{
synchronized(_doneMutex)
{
- _done = true;
- _doneMutex.notify();
+ if(!setCallbackInProgress(false))
+ {
+ return;
+ }
+
+ _hook.run();
+
+ clearCallbackInProgress();
+
+ //
+ // Don't bother to join with main, we're done.
+ //
}
}
- private boolean _done;
- private java.lang.Object _doneMutex = new java.lang.Object();
+ private Thread _hook;
}
private static String _appName;
private static Communicator _communicator;
- private static DestroyHook _destroyHook;
- private static ShutdownHook _shutdownHook;
+ private static AppHook _appHook;
private static java.lang.Object _mutex = new java.lang.Object();
private static boolean _callbackInProgress = false;
private static boolean _destroyed = false;