FELIX-4350 Fix race between activation and deactivation. Problem with ServiceTracker exposed and ignored
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1549723 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index 73552eb..ae4ade4 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -263,6 +263,7 @@
public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
{
+ refPair.setDeleted( true );
if ( !isOptional() )
{
if (getTracker().isEmpty())
@@ -351,6 +352,7 @@
public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
{
m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+ refPair.setDeleted( true );
boolean unbind = isOptional() || !getTracker().isEmpty();
if ( unbind )
{
@@ -469,6 +471,7 @@
public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
{
m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticGreedy removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+ refPair.setDeleted( true );
tracked( trackingCount );
if ( isActive() )
{
@@ -566,6 +569,7 @@
public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
{
m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticReluctant removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+ refPair.setDeleted( true );
tracked( trackingCount );
Collection<RefPair<T>> refs = this.refs.get();
if ( isActive() && refs != null )
@@ -737,6 +741,7 @@
public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
{
m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleDynamic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+ refPair.setDeleted( true );
boolean deactivate = false;
boolean untracked = true;
RefPair<T> oldRefPair = null;
@@ -937,6 +942,10 @@
public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
{
m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+ if ( refPair != null ) //TODO needs investigation
+ {
+ refPair.setDeleted( true );
+ }
this.trackingCount = trackingCount;
tracked( trackingCount );
boolean reactivate;
@@ -1427,7 +1436,7 @@
new Object[]{ getName(), success, refs }, null );
for ( RefPair<T> refPair : refs )
{
- if ( !refPair.isFailed() )
+ if ( !refPair.isDeleted() && !refPair.isFailed() )
{
if ( !doInvokeBindMethod( componentInstance, refPair ) )
{
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
index cee9171..3f9a04a 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
@@ -33,6 +33,7 @@
private AtomicReference<T> serviceObjectRef = new AtomicReference<T>();
private boolean failed;
+ private volatile boolean deleted;
public RefPair( ServiceReference<T> ref )
{
@@ -74,6 +75,15 @@
return failed;
}
+ public boolean isDeleted()
+ {
+ return deleted;
+ }
+
+ public void setDeleted(boolean deleted)
+ {
+ this.deleted = deleted;
+ }
@Override
public String toString()
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
index d22005f..97efc21 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
@@ -254,13 +254,17 @@
protected static void delay()
{
+ delay(300);
+ }
+
+ protected static void delay(int millis)
+ {
try
{
- Thread.sleep( 300 );
+ Thread.sleep(millis);
}
- catch ( InterruptedException ie )
+ catch (InterruptedException ie)
{
- // dont care
}
}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/Felix4350Test.java b/scr/src/test/java/org/apache/felix/scr/integration/Felix4350Test.java
index 57c5959..569310c 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/Felix4350Test.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/Felix4350Test.java
@@ -45,44 +45,35 @@
// uncomment to enable debugging of this test class
// paxRunnerVmOption = DEBUG_VM_OPTION;
descriptorFile = "/integration_test_FELIX_4350.xml";
- restrictedLogging = true;
//comment to get debug logging if the test fails.
// DS_LOGLEVEL = "warn";
}
- @Inject
- protected BundleContext bundleContext;
-
@Test
- @Ignore
public void test_unbind_while_activating_single_static()
{
doTest("SingleStatic");
}
@Test
- @Ignore
public void test_unbind_while_activating_single_dynamic()
{
doTest("SingleDynamic");
}
@Test
- @Ignore
public void test_unbind_while_activating_multiple_dynamic()
{
doTest("MultipleDynamic");
}
@Test
- @Ignore
public void test_unbind_while_activating_multiple_static_greedy()
{
doTest("MultipleStaticGreedy");
}
@Test
- @Ignore
public void test_unbind_while_activating_multiple_static_reluctant()
{
doTest("MultipleStaticReluctant");
@@ -126,15 +117,4 @@
TestCase.assertNull(mainCompInst);
}
- protected static void delay(int millis)
- {
- try
- {
- Thread.sleep(millis);
- }
- catch (InterruptedException ie)
- {
- }
- }
-
}