Return-Path: Delivered-To: apmail-jakarta-avalon-cvs-archive@apache.org Received: (qmail 82966 invoked from network); 4 Dec 2002 02:52:44 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 4 Dec 2002 02:52:44 -0000 Received: (qmail 14270 invoked by uid 97); 4 Dec 2002 02:53:57 -0000 Delivered-To: qmlist-jakarta-archive-avalon-cvs@jakarta.apache.org Received: (qmail 14236 invoked by uid 97); 4 Dec 2002 02:53:56 -0000 Mailing-List: contact avalon-cvs-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Avalon CVS List" Reply-To: "Avalon Developers List" Delivered-To: mailing list avalon-cvs@jakarta.apache.org Received: (qmail 14225 invoked by uid 97); 4 Dec 2002 02:53:55 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Date: 4 Dec 2002 02:52:38 -0000 Message-ID: <20021204025238.51617.qmail@icarus.apache.org> From: proyal@apache.org To: jakarta-avalon-excalibur-cvs@apache.org Subject: cvs commit: jakarta-avalon-excalibur/event/src/java/org/apache/excalibur/event/command AbstractThreadManager.java EventThreadPool.java TPCThreadManager.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N proyal 2002/12/03 18:52:37 Modified: event/src/java/org/apache/excalibur/event/command AbstractThreadManager.java EventThreadPool.java TPCThreadManager.java Log: Patch from Christopher Kohlhaas The bug sometimes occurs on disposing of the TPCThreadManager and results in: Unexpected condition while releasing worker: Thread[TPCThreadManager Worker #0,5,TPCThreadManager] java.lang.NullPointerException at org.apache.excalibur.event.command.EventThreadPool.releaseWorker(EventThreadPool.java:141) at org.apache.excalibur.thread.impl.WorkerThread.recycleThread(WorkerThread.java:134) at org.apache.excalibur.thread.impl.WorkerThread.run(WorkerThread.java:123) It's caused by Threads in the EventThreadPool that were still running after disposing of the Pool. Revision Changes Path 1.12 +49 -10 jakarta-avalon-excalibur/event/src/java/org/apache/excalibur/event/command/AbstractThreadManager.java Index: AbstractThreadManager.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/event/src/java/org/apache/excalibur/event/command/AbstractThreadManager.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- AbstractThreadManager.java 2 Oct 2002 17:49:20 -0000 1.11 +++ AbstractThreadManager.java 4 Dec 2002 02:52:37 -0000 1.12 @@ -52,7 +52,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; -import EDU.oswego.cs.dl.util.concurrent.ReentrantLock; + import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.logger.AbstractLogEnabled; @@ -61,6 +61,8 @@ import org.apache.excalibur.thread.ThreadControl; import org.apache.excalibur.thread.ThreadPool; +import EDU.oswego.cs.dl.util.concurrent.ReentrantLock; + /** * Abstract base class for a ThreadManager that has a single ThreadPool for * all pipelines @@ -207,13 +209,17 @@ if( m_pipelines.isEmpty() ) { m_done = true; - m_threadControl.join( 1000 ); } } finally { m_mutex.release(); } + + if( m_done ) + { + m_threadControl.join( 1000 ); + } } catch( InterruptedException ie ) { @@ -234,26 +240,26 @@ try { + // Aquire mutex to clear pipelines and set the m_done flag m_mutex.acquire(); try { m_done = true; - m_threadControl.join( 1000 ); - Iterator it = m_controls.iterator(); while( it.hasNext() ) { - ( (ThreadControl)it.next() ).join( 1000 ); + ( ( ThreadControl ) it.next() ).join( 1000 ); } - m_pipelines.clear(); } finally { + // C.K. We must release the mutex to give the manager thread a chance to terminate. m_mutex.release(); } + m_threadControl.join( 1000 ); } catch( InterruptedException ie ) { @@ -261,6 +267,7 @@ } } + /** * Get rid of the ThreadManager. */ @@ -268,10 +275,39 @@ { deregisterAll(); + if( m_threadControl != null && !m_threadControl.isFinished() ) + { + if( getLogger().isErrorEnabled() ) + { + getLogger().error( "The ThreadManager management thread is still active." ); + } + } + m_threadControl = null; } /** + * Return the thread controlls of all active threads + * (excluding the ThreadManager management thread) + */ + protected ThreadControl[] getThreadControls() + { + try + { + m_mutex.acquire(); + return ( ThreadControl[] ) m_controls.toArray( new ThreadControl[0] ); + } + catch( InterruptedException ie ) + { + return new ThreadControl[0]; + } + finally + { + m_mutex.release(); + } + } + + /** * The code that is run in the background to manage the ThreadPool and the * EventPipelines */ @@ -289,7 +325,7 @@ while( i.hasNext() ) { - PipelineRunner nextRunner = (PipelineRunner)i.next(); + PipelineRunner nextRunner = ( PipelineRunner ) i.next(); ThreadControl control = null; while( control == null ) @@ -330,8 +366,11 @@ while( it.hasNext() ) { - ThreadControl control = (ThreadControl)it.next(); - if( control.isFinished() ) it.remove(); + ThreadControl control = ( ThreadControl ) it.next(); + if( control.isFinished() ) + { + it.remove(); + } } m_mutex.release(); @@ -386,7 +425,7 @@ { try { - handler.handleEvents( sources[ i ].dequeueAll() ); + handler.handleEvents( sources[i].dequeueAll() ); } catch( RuntimeException e ) { 1.6 +12 -8 jakarta-avalon-excalibur/event/src/java/org/apache/excalibur/event/command/EventThreadPool.java Index: EventThreadPool.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/event/src/java/org/apache/excalibur/event/command/EventThreadPool.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- EventThreadPool.java 18 Oct 2002 02:22:39 -0000 1.5 +++ EventThreadPool.java 4 Dec 2002 02:52:37 -0000 1.6 @@ -106,7 +106,7 @@ { if( object instanceof WorkerThread ) { - destroyWorker( (WorkerThread)object ); + destroyWorker( ( WorkerThread ) object ); } } @@ -122,7 +122,7 @@ */ protected WorkerThread getWorker() { - final WorkerThread thread = (WorkerThread)m_pool.acquire(); + final WorkerThread thread = ( WorkerThread ) m_pool.acquire(); if( null == thread ) { final String message = @@ -135,16 +135,20 @@ protected void releaseWorker( final WorkerThread worker ) { - try + worker.interrupted(); + + if( m_pool != null ) { - worker.interrupted(); m_pool.release( worker ); } - catch( Throwable e ) + else { - // trying to figure out why a NullPointer exeception can occur ... - System.err.println( "Unexpected condition while releasing worker: " + worker ); - e.printStackTrace(); + final String message = "ThreadPool disposed before workerThread has finished. " + + "Please call dispose(Worker) before." + worker; + + System.err.println( message ); + + Thread.currentThread().dumpStack(); } } } 1.33 +13 -1 jakarta-avalon-excalibur/event/src/java/org/apache/excalibur/event/command/TPCThreadManager.java Index: TPCThreadManager.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/event/src/java/org/apache/excalibur/event/command/TPCThreadManager.java,v retrieving revision 1.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- TPCThreadManager.java 2 Oct 2002 01:46:57 -0000 1.32 +++ TPCThreadManager.java 4 Dec 2002 02:52:37 -0000 1.33 @@ -53,6 +53,7 @@ import org.apache.avalon.framework.parameters.ParameterException; import org.apache.avalon.framework.parameters.Parameterizable; import org.apache.avalon.framework.parameters.Parameters; +import org.apache.excalibur.thread.ThreadControl; import org.apache.excalibur.util.SystemUtil; /** @@ -132,7 +133,7 @@ } m_tpool = new EventThreadPool( "TPCThreadManager", - ( m_processors * m_threadsPerProcessor ) + 1, (int)m_blockTimeout ); + ( m_processors * m_threadsPerProcessor ) + 1, ( int ) m_blockTimeout ); if( null == getLogger() ) { @@ -147,6 +148,17 @@ public final void dispose() { super.dispose(); + + // We should dispose all active threads + final ThreadControl[] threads = getThreadControls(); + + for( int i = 0; i < threads.length; i++ ) + { + if( !threads[i].isFinished() ) + { + m_tpool.dispose( threads[i] ); + } + } m_tpool.dispose(); } -- To unsubscribe, e-mail: For additional commands, e-mail: