On 8/2/13 09:23 , gno...@apache.org wrote:
Author: gnodet
Date: Fri Aug  2 13:23:13 2013
New Revision: 1509692

URL: http://svn.apache.org/r1509692
Log:
[FELIX-4190] The framework should not hold any lock while calling 
ServiceFactory#unget

This commit should be quite safe as getUsingBundles() and ungetService() are 
already thread safe, and there's no possibility for the bundle to acquire a new 
reference to the service because the service has already been unregistered

Technically, I think this patch is not correct.

We specifically allow for bundles that already hold the service reference to acquire the service object while a service is being unregistered (see comments in ServiceRegistry.unregisterService()). This means that a bundle that already holds the service reference could, technically, acquire the unregistering service just after you call getUsingBundles(), thus we wouldn't be forcing it to unget.

The only way I think we can do what you want is to somehow acquire the registry lock (i.e., this) again and put us into some new state that doesn't allow any more bundles to acquire the unregistering service...or perhaps by adding something to the service registration to put it into a new state where it won't return anything from getService. Then we could release the registry lock and continue with what you have.

-> richard


Modified:
     
felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java

Modified: 
felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java?rev=1509692&r1=1509691&r2=1509692&view=diff
==============================================================================
--- 
felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
 (original)
+++ 
felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
 Fri Aug  2 13:23:13 2013
@@ -153,16 +153,13 @@ public class ServiceRegistry
          }
// Now forcibly unget the service object for all stubborn clients.
-        synchronized (this)
+        Bundle[] clients = getUsingBundles(reg.getReference());
+        for (int i = 0; (clients != null) && (i < clients.length); i++)
          {
-            Bundle[] clients = getUsingBundles(reg.getReference());
-            for (int i = 0; (clients != null) && (i < clients.length); i++)
-            {
-                while (ungetService(clients[i], reg.getReference()))
-                    ; // Keep removing until it is no longer possible
-            }
-            ((ServiceRegistrationImpl) reg).invalidate();
+            while (ungetService(clients[i], reg.getReference()))
+                ; // Keep removing until it is no longer possible
          }
+        ((ServiceRegistrationImpl) reg).invalidate();
      }
/**



Reply via email to