Java Interrupts
As of Ice 3.6, Java applications can safely interrupt a thread that calls a blocking Ice API.
You must enable the Ice.ThreadInterruptSafe
property to use interrupts. Enabling interrupts causes Ice to disable message buffer caching, which may incur a slight performance penalty.
With interrupt support enabled, Ice guarantees that every call into the run time that could potentially block indefinitely is an interruption point. On entry, an interruption point raises the unchecked exception Ice.OperationInterruptedException
immediately if the current thread's interrupted flag is true. If the application interrupts the run time after the interruption point has begun its processing, the interruption point will either raise Ice.OperationInterruptedException
or return control to the application with the thread's interrupted flag set. Under no circumstances will Ice silently discard an interrupt.
For example, the following code shows how to interrupt a thread that's blocked while making a synchronous proxy invocation:
Thread proxyThread = Thread.currentThread(); AccountPrx account = // get proxy... try { String name = account.getName(); // Blocks calling thread ... } catch (Ice.OperationInterruptedException ex) { // The invocation was interrupted. } // At this point either the invocation was interrupted with an // OperationInterruptedException or proxyThread.isInterrupted() is true. // In another thread either just prior to or during the getName() invocation. proxyThread.interrupt();
Here is a similar example that uses the asynchronous proxy API instead:
Thread proxyThread = Thread.currentThread(); AccountPrx account = // get proxy... Ice.AsyncResult r = account.begin_getName(); // Never blocks try { // do more work String name = account.end_getName(r); // May block calling thread ... } catch (Ice.OperationInterruptedException ex) { // The invocation was interrupted. } // At this point either the invocation was interrupted with an // OperationInterruptedException or proxyThread.isInterrupted() is true. // In another thread either just prior to or during the getName() invocation. proxyThread.interrupt();
Synchronous proxy invocations are interruption points. For an asynchronous proxy invocation, the begin_
method never blocks and therefore it is not an interruption point, however the end_
method is an interruption point.
Additionally, all of the methods listed in Blocking API Calls are also interruption points. In the specific case of Communicator.destroy()
, we recommend calling destroy
in a loop as shown below:
while(true) { try { communicator.destroy(); break; } catch(Ice.OperationInterruptedException ex) { continue; } }
Interrupting a call to destroy
could leave the Ice run time in a partially-destroyed state; calling destroy
again as we've done here ensures Ice can finish reclaiming the communicator's resources.