You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2018/11/03 13:45:23 UTC

svn commit: r1845660 - in /felix/trunk/scr/src/main/java/org/apache/felix/scr/impl: helper/ComponentServiceObjectsHelper.java manager/DependencyManager.java manager/MultiplePrototypeRefPair.java manager/RefPair.java manager/SinglePrototypeRefPair.java

Author: cziegeler
Date: Sat Nov  3 13:45:22 2018
New Revision: 1845660

URL: http://svn.apache.org/viewvc?rev=1845660&view=rev
Log:
FELIX-5974 : Prototype scope references are not released on deactivation. Applied patch from Tim Ward

Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java?rev=1845660&r1=1845659&r2=1845660&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java Sat Nov  3 13:45:22 2018
@@ -41,8 +41,6 @@ public class ComponentServiceObjectsHelp
 
     private final List<ComponentServiceObjectsImpl> closedServices = new ArrayList<ComponentServiceObjectsImpl>();
 
-    private final ConcurrentMap<ServiceReference, Object> prototypeInstances = new ConcurrentHashMap<ServiceReference, Object>();
-
     public ComponentServiceObjectsHelper(final BundleContext bundleContext)
     {
         this.bundleContext = bundleContext;
@@ -65,7 +63,6 @@ public class ComponentServiceObjectsHelp
         {
         	cso.deactivate();
         }
-        prototypeInstances.clear();
     }
 
     public ComponentServiceObjects getServiceObjects(final ServiceReference<?> ref)
@@ -97,24 +94,11 @@ public class ComponentServiceObjectsHelp
         	}
             cso.close();
         }
-        prototypeInstances.remove(ref);
     }
 
-    public <T> T getPrototypeRefInstance(final ServiceReference<T> ref, ServiceObjects<T> serviceObjects)
+    public <T> T getPrototypeRefInstance(final ServiceReference<T> ref)
     {
-    	T service = (T) prototypeInstances.get(ref);
-    	if ( service == null )
-    	{
-    		service = serviceObjects.getService();
-    		T oldService = (T)prototypeInstances.putIfAbsent(ref, service);
-    		if ( oldService != null )
-    		{
-    			// another thread created the instance already
-    			serviceObjects.ungetService(service);
-    			service = oldService;
-    		}
-    	}
-    	return service;
+    	return (T) getServiceObjects(ref).getService();
     }
 
     private static final class ComponentServiceObjectsImpl implements ComponentServiceObjects

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1845660&r1=1845659&r2=1845660&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java Sat Nov  3 13:45:22 2018
@@ -1681,7 +1681,9 @@ public class DependencyManager<S, T> imp
             {
                 invokeUnbindMethod(componentContext, boundRef, trackingCount.get(), edgeInfo);
             }
-
+            
+            boundRef.unsetServiceObject(componentContext);
+            
         }
         latch.countDown();
     }
@@ -2320,9 +2322,9 @@ public class DependencyManager<S, T> imp
         }
         if (m_componentManager.getComponentMetadata().getServiceScope() == Scope.singleton)
         {
-            return new SinglePrototypeRefPair<>(m_componentManager.getBundleContext(), serviceReference);
+            return new SinglePrototypeRefPair<>(serviceReference);
         }
-        return new MultiplePrototypeRefPair<>(m_componentManager.getBundleContext(), serviceReference);
+        return new MultiplePrototypeRefPair<>(serviceReference);
     }
 
     private void deactivateComponentManager()

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java?rev=1845660&r1=1845659&r2=1845660&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java Sat Nov  3 13:45:22 2018
@@ -21,11 +21,11 @@
 package org.apache.felix.scr.impl.manager;
 
 import java.util.Iterator;
+import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
@@ -34,19 +34,11 @@ import org.osgi.service.log.LogService;
  */
 public class MultiplePrototypeRefPair<S, T> extends RefPair<S, T>
 {
-    private final ServiceObjects<T> serviceObjects;
     private final ConcurrentMap<ComponentContextImpl<S>, T> instances = new ConcurrentHashMap<>();
 
-    public MultiplePrototypeRefPair( BundleContext context, ServiceReference<T> ref )
+    public MultiplePrototypeRefPair( ServiceReference<T> ref )
     {
         super(ref);
-        this.serviceObjects = context.getServiceObjects(ref);
-    }
-
-    @Override
-    public ServiceObjects<T> getServiceObjects()
-    {
-        return serviceObjects;
     }
 
     @Override
@@ -58,7 +50,7 @@ public class MultiplePrototypeRefPair<S,
     @Override
     public boolean setServiceObject(ComponentContextImpl<S> key, T serviceObject)
     {
-        return instances.putIfAbsent(key, serviceObject) == null;
+        return instances.putIfAbsent( key, serviceObject ) == null;
     }
 
     @Override
@@ -66,22 +58,20 @@ public class MultiplePrototypeRefPair<S,
     {
     	if ( key == null )
     	{
-			try 
+			final Iterator<Entry<ComponentContextImpl<S>, T>> iter = instances.entrySet().iterator();
+			while ( iter.hasNext() ) 
 			{
-				final Iterator<T> iter = instances.values().iterator();
-				while ( iter.hasNext() ) 
-				{
-    			    this.serviceObjects.ungetService(iter.next());
-    			} 
-    		}
-    		catch (final IllegalStateException ise)
-    		{
-    			// ignore
-   			}
+				Entry<ComponentContextImpl<S>, T> e = iter.next();
+				doUngetService( e.getKey(), e.getValue() );
+   			} 
     		instances.clear();
     		return null ;
     	}
-        return instances.remove(key);
+        T service = instances.remove( key );
+        if(service != null) {
+        	doUngetService( key, service );
+        }
+		return service;
     }
 
     @Override
@@ -93,7 +83,7 @@ public class MultiplePrototypeRefPair<S,
     @Override
     public boolean getServiceObject(ComponentContextImpl<S> key, BundleContext context)
     {
-    	final T service = key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef(), serviceObjects);
+    	final T service = key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
         if ( service == null )
         {
             setFailed();
@@ -105,8 +95,19 @@ public class MultiplePrototypeRefPair<S,
         if (!setServiceObject(key, service))
         {
             // Another thread got the service before, so unget our
-            serviceObjects.ungetService( service );
+        	doUngetService( key, service );
         }
         return true;
     }
+
+	private void doUngetService(ComponentContextImpl<S> key, final T service) {
+		try 
+		{
+			key.getComponentServiceObjectsHelper().getServiceObjects(getRef()).ungetService( service );
+		}
+		catch ( final IllegalStateException ise )
+		{
+			// ignore
+		}
+	}
 }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java?rev=1845660&r1=1845659&r2=1845660&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java Sat Nov  3 13:45:22 2018
@@ -44,11 +44,6 @@ public abstract class RefPair<S, T>
         return ref;
     }
 
-    public ServiceObjects<T> getServiceObjects()
-    {
-        return null;
-    }
-
     public abstract boolean getServiceObject( ComponentContextImpl<S> key, BundleContext context );
 
     public abstract T getServiceObject(ComponentContextImpl<S> key);

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java?rev=1845660&r1=1845659&r2=1845660&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java Sat Nov  3 13:45:22 2018
@@ -21,7 +21,6 @@
 package org.apache.felix.scr.impl.manager;
 
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
@@ -30,18 +29,9 @@ import org.osgi.service.log.LogService;
  */
 public class SinglePrototypeRefPair<S, T> extends SingleRefPair<S, T>
 {
-    private final ServiceObjects<T> serviceObjects;
-
-    public SinglePrototypeRefPair( BundleContext context, ServiceReference<T> ref )
+    public SinglePrototypeRefPair( ServiceReference<T> ref )
     {
         super(ref);
-        this.serviceObjects = context.getServiceObjects(ref);
-    }
-
-    @Override
-    public ServiceObjects<T> getServiceObjects()
-    {
-        return serviceObjects;
     }
 
     @Override
@@ -53,7 +43,7 @@ public class SinglePrototypeRefPair<S, T
     @Override
     public boolean getServiceObject(ComponentContextImpl<S> key, BundleContext context)
     {
-    	final T service = key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef(), serviceObjects);
+    	final T service = key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
         if ( service == null )
         {
             setFailed();
@@ -65,9 +55,31 @@ public class SinglePrototypeRefPair<S, T
         if (!setServiceObject(key, service))
         {
             // Another thread got the service before, so unget our
-            serviceObjects.ungetService( service );
+        	doUngetService(key, service);
         }
         return true;
     }
 
+    @Override
+    public T unsetServiceObject(ComponentContextImpl<S> key)
+    {
+    	final T service = super.unsetServiceObject(key);
+    	if ( service != null )
+    	{
+			doUngetService(key, service);
+    	}
+    	return null ;
+    }
+
+	private void doUngetService(ComponentContextImpl<S> key, final T service) {
+		try 
+		{
+			key.getComponentServiceObjectsHelper().getServiceObjects(getRef()).ungetService(service);
+		}
+		catch (final IllegalStateException ise)
+		{
+			// ignore
+		}
+	}
+    
 }