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