--- src/EDU/oswego/cs/dl/util/concurrent/PooledExecutor.java 2007-09-11 14:32:37.000000000 +0200 +++ /home/ejort/temp/PooledExecutor.java 2005-07-15 20:47:08.000000000 +0200 @@ -27,10 +27,11 @@ Simplify locking scheme 25jan2001 dl {get,set}BlockedExecutionHandler now public 17may2002 dl null out task var in worker run to enable GC. 30aug2003 dl check for new tasks when timing out 18feb2004 dl replace dead thread if no others left + 23jun2004 dl fix shutdownAfterProcessingCurrentlyQueuedTasks */ package EDU.oswego.cs.dl.util.concurrent; import java.util.*; @@ -589,15 +590,27 @@ * Terminate threads after processing all elements currently in * queue. Any tasks entered after this point will be handled by the * given BlockedExecutionHandler. A shut down pool cannot be * restarted. **/ - public synchronized void shutdownAfterProcessingCurrentlyQueuedTasks(BlockedExecutionHandler handler) { - setBlockedExecutionHandler(handler); - shutdown_ = true; - if (poolSize_ == 0) // disable new thread construction when idle - minimumPoolSize_ = maximumPoolSize_ = 0; + public void shutdownAfterProcessingCurrentlyQueuedTasks(BlockedExecutionHandler handler) { + synchronized(this) { + setBlockedExecutionHandler(handler); + shutdown_ = true; + if (poolSize_ == 0) // disable new thread construction when idle + minimumPoolSize_ = maximumPoolSize_ = 0; + } + // Try to add a final task to interrupt remaining threads waiting + // on handoff that will never otherwise get new tasks. If the + // offer fails, no threads such could be waiting + try { + Runnable r = new Runnable() { public void run() { interruptAll(); }}; + handOff_.offer(r, 0); + } + catch(InterruptedException ie) { + Thread.currentThread().interrupt(); + } } /** * Return true if a shutDown method has succeeded in terminating all * threads.