FELIX-4977 Concurrency issues with Service Registry.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1693602 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
index 7f1132a..46334ce 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -380,6 +380,8 @@
}
// Increment the Atomic Long by 1, and ensure the result is at least 1.
+ // This method uses a loop, optimistic algorithm to do this in a threadsafe
+ // way without locks.
private void incrementToPositiveValue(AtomicLong al)
{
boolean success = false;
@@ -469,9 +471,11 @@
usage.m_svcHolderRef.set(null);
}
- // If the registration is invalid or the usage count has reached
- // zero, then flush it.
- if (!reg.isValid())
+ // If the registration is invalid or the usage count for a prototype
+ // reached zero, then flush it. Non-prototype services are not flushed
+ // on ungetService() when they reach 0 as this introduces a race
+ // condition of concurrently the same service is obtained via getService()
+ if (!reg.isValid() || (count <= 0 && svcObj != null))
{
flushUsageCount(bundle, ref, usage);
}