avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pro...@apache.org
Subject cvs commit: jakarta-avalon-excalibur/event/src/java/org/apache/excalibur/event/command AbstractThreadManager.java EventThreadPool.java TPCThreadManager.java
Date Wed, 04 Dec 2002 02:52:38 GMT
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 <christophert@einfachanders.de>
  
  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:   <mailto:avalon-cvs-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-cvs-help@jakarta.apache.org>


Mime
View raw message