FELIX-4977 Service Registry Concurrency - add extra check before ungetService()


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1693609 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 46334ce..be78da4 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -452,12 +452,17 @@
 
                     if (svc != null)
                     {
-                        if (usage.m_svcHolderRef.compareAndSet(holder, null))
+                        // Check the count again to ensure that nobody else has just
+                        // obtained the service again
+                        if (usage.m_count.get() <= 0)
                         {
-                            // Remove reference from usages array.
-                            ((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
-                                .getRegistration().ungetService(bundle, svc);
+                            if (usage.m_svcHolderRef.compareAndSet(holder, null))
+                            {
+                                // Remove reference from usages array.
+                                ((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
+                                    .getRegistration().ungetService(bundle, svc);
 
+                            }
                         }
                     }
                 }
diff --git a/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java b/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
index 440617d..ecb7e2e 100644
--- a/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
@@ -1053,14 +1053,12 @@
 
                     final class ObserverImpl implements Observer
                     {
-//                        private volatile int counter = 0;
                         private final AtomicInteger counter = new AtomicInteger();
                         public volatile boolean active = true;
 
                         @Override
                         public void update(Observable o, Object arg)
                         {
-//                            counter++; // Not completely atomic, but that doesn't matter here.
                             counter.incrementAndGet();
                             if ( !active )
                             {