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--;
- }
}