You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2011/07/28 10:11:04 UTC

svn commit: r1151755 - in /felix/trunk/eventadmin/impl: changelog.txt src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncDeliverTasks.java src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncThread.java

Author: cziegeler
Date: Thu Jul 28 08:11:03 2011
New Revision: 1151755

URL: http://svn.apache.org/viewvc?rev=1151755&view=rev
Log:
FELIX-3055 : Event Admin deadlocks when sendEvent is called from within a handleEvent method

Modified:
    felix/trunk/eventadmin/impl/changelog.txt
    felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncDeliverTasks.java
    felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncThread.java

Modified: felix/trunk/eventadmin/impl/changelog.txt
URL: http://svn.apache.org/viewvc/felix/trunk/eventadmin/impl/changelog.txt?rev=1151755&r1=1151754&r2=1151755&view=diff
==============================================================================
--- felix/trunk/eventadmin/impl/changelog.txt (original)
+++ felix/trunk/eventadmin/impl/changelog.txt Thu Jul 28 08:11:03 2011
@@ -5,7 +5,7 @@ Changes from 1.2.12 to 1.2.14
     * [FELIX-2997] - java.lang.NullPointerException during shutdown while sending events
     * [FELIX-3002] - Embed the OBR specific information for the EventAdmin bundle in the manifest
     * [FELIX-3053] - Potential deadlock if event handler throws Throwable and is bypassing timeout handling
-    
+    * [FELIX-3055] - Event Admin deadlocks when sendEvent is called from within a handleEvent method
 
 
 Changes from 1.2.10 to 1.2.12

Modified: felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncDeliverTasks.java
URL: http://svn.apache.org/viewvc/felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncDeliverTasks.java?rev=1151755&r1=1151754&r2=1151755&view=diff
==============================================================================
--- felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncDeliverTasks.java (original)
+++ felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncDeliverTasks.java Thu Jul 28 08:11:03 2011
@@ -197,18 +197,7 @@ public class SyncDeliverTasks implements
     public void execute(final List tasks)
     {
         final Thread sleepingThread = Thread.currentThread();
-        SyncThread syncThread = sleepingThread instanceof SyncThread ? (SyncThread)sleepingThread : null;
-        final Rendezvous cascadingBarrier = new Rendezvous();
-        // check if this is a cascaded event sending
-        if ( syncThread != null )
-        {
-            // wake up outer thread
-            if ( syncThread.isTopMostHandler() )
-            {
-                syncThread.getTimerBarrier().waitForRendezvous();
-            }
-            syncThread.innerEventHandlingStart();
-        }
+        final SyncThread syncThread = sleepingThread instanceof SyncThread ? (SyncThread)sleepingThread : null;
 
         final Iterator i = tasks.iterator();
         while ( i.hasNext() )
@@ -220,6 +209,17 @@ public class SyncDeliverTasks implements
                 // no timeout, we can directly execute
                 task.execute();
             }
+            else if ( syncThread != null )
+            {
+                // if this is a cascaded event, we directly use this thread
+                // otherwise we could end up in a starvation
+                final long startTime = System.currentTimeMillis();
+                task.execute();
+                if ( System.currentTimeMillis() - startTime > m_timeout )
+                {
+                    task.blackListHandler();
+                }
+            }
             else
             {
                 final Rendezvous startBarrier = new Rendezvous();
@@ -228,8 +228,6 @@ public class SyncDeliverTasks implements
                 {
                     public void run()
                     {
-                        final SyncThread myThread = (SyncThread)Thread.currentThread();
-                        myThread.init(timerBarrier, cascadingBarrier);
                         try
                         {
                             // notify the outer thread to start the timer
@@ -243,58 +241,26 @@ public class SyncDeliverTasks implements
                         {
                             // this can happen on shutdown, so we ignore it
                         }
-                        finally
-                        {
-                            myThread.cleanup();
-                        }
                     }
                 });
                 // we wait for the inner thread to start
                 startBarrier.waitForRendezvous();
 
                 // timeout handling
-                boolean finished;
-                long sleepTime = m_timeout;
-                do {
-                    finished = true;
-                    // we sleep for the sleep time
-                    // if someone wakes us up it's the inner task who either
-                    // has finished or a cascading event
-                    long startTime = System.currentTimeMillis();
-                    try
-                    {
-                        timerBarrier.waitAttemptForRendezvous(sleepTime);
-                        // if this occurs no timeout occured or we have a cascaded event
-                        if ( !task.finished() )
-                        {
-                            // adjust remaining sleep time
-                            sleepTime = m_timeout - (System.currentTimeMillis() - startTime);
-                            cascadingBarrier.waitForRendezvous();
-                            finished = task.finished();
-                        }
-                    }
-                    catch (TimeoutException ie)
-                    {
-                        // if we timed out, we have to blacklist the handler
-                        task.blackListHandler();
-                    }
+                final long sleepTime = m_timeout;
+                // we sleep for the sleep time
+                // if someone wakes us up it's the finished inner task
+                try
+                {
+                    timerBarrier.waitAttemptForRendezvous(sleepTime);
                 }
-                while ( !finished );
-
-            }
-        }
-        // wake up outer thread again if cascaded
-
-        if ( syncThread != null )
-        {
-            syncThread.innerEventHandlingStopped();
-            if ( syncThread.isTopMostHandler() )
-            {
-                if ( !syncThread.getTimerBarrier().isTimedOut() ) {
-                    syncThread.getCascadingBarrier().waitForRendezvous();
+                catch (TimeoutException ie)
+                {
+                    // if we timed out, we have to blacklist the handler
+                    task.blackListHandler();
                 }
+
             }
         }
-
     }
 }

Modified: felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncThread.java
URL: http://svn.apache.org/viewvc/felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncThread.java?rev=1151755&r1=1151754&r2=1151755&view=diff
==============================================================================
--- felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncThread.java (original)
+++ felix/trunk/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/SyncThread.java Thu Jul 28 08:11:03 2011
@@ -21,20 +21,13 @@ package org.apache.felix.eventadmin.impl
 /**
  * This thread class is used for sending the events
  * synchronously.
- * It handles cascaded synchronous events.
+ * It acts like a marker.
  *
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class SyncThread extends Thread
 {
 
-    /** Counter to track the nesting level. */
-    private volatile int counter;
-
-    /** The barriers for synchronizing. */
-    private volatile Rendezvous timerBarrier;
-    private volatile Rendezvous cascadingBarrier;
-
     /**
      * Constructor used by the thread pool.
      */
@@ -42,41 +35,4 @@ public class SyncThread extends Thread
     {
         super(target);
     }
-
-    public void init(final Rendezvous timerBarrier, final Rendezvous cascadingBarrier)
-    {
-        this.timerBarrier = timerBarrier;
-        this.cascadingBarrier = cascadingBarrier;
-    }
-
-    public void cleanup()
-    {
-        this.timerBarrier = null;
-        this.cascadingBarrier = null;
-    }
-
-    public Rendezvous getTimerBarrier()
-    {
-        return timerBarrier;
-    }
-
-    public Rendezvous getCascadingBarrier()
-    {
-        return cascadingBarrier;
-    }
-
-    public boolean isTopMostHandler()
-    {
-        return counter == 0;
-    }
-
-    public void innerEventHandlingStart()
-    {
-        counter++;
-    }
-
-    public void innerEventHandlingStopped()
-    {
-        counter--;
-    }
 }