Author: rotty3000
Date: Wed Jan 16 15:51:19 2019
New Revision: 1851459

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

Modified:
    
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java
    
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
    
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
    
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
    
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java

Modified: 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java
URL: 
http://svn.apache.org/viewvc/felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java?rev=1851459&r1=1851458&r2=1851459&view=diff
==============================================================================
--- 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java
 (original)
+++ 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java
 Wed Jan 16 15:51:19 2019
@@ -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/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: 
http://svn.apache.org/viewvc/felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1851459&r1=1851458&r2=1851459&view=diff
==============================================================================
--- 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
 (original)
+++ 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
 Wed Jan 16 15:51:19 2019
@@ -1601,7 +1601,9 @@ public class DependencyManager<S, T> imp
             {
                 invokeUnbindMethod(componentContext, boundRef, 
trackingCount.get(), edgeInfo);
             }
-
+            
+            boundRef.unsetServiceObject(componentContext);
+            
         }
         latch.countDown();
     }
@@ -2240,9 +2242,9 @@ public class DependencyManager<S, T> imp
         }
         if (m_componentManager.getComponentMetadata().getServiceScope() == 
Scope.singleton)
         {
-            return new SinglePrototypeRefPair<S, 
T>(m_componentManager.getBundleContext(), serviceReference);
+            return new SinglePrototypeRefPair<>(serviceReference);
         }
-        return new MultiplePrototypeRefPair<S, 
T>(m_componentManager.getBundleContext(), serviceReference);
+        return new MultiplePrototypeRefPair<>(serviceReference);
     }
 
     private void deactivateComponentManager()

Modified: 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
URL: 
http://svn.apache.org/viewvc/felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java?rev=1851459&r1=1851458&r2=1851459&view=diff
==============================================================================
--- 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
 (original)
+++ 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/MultiplePrototypeRefPair.java
 Wed Jan 16 15:51:19 2019
@@ -21,12 +21,12 @@
 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.apache.felix.scr.impl.helper.SimpleLogger;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
@@ -35,19 +35,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<ComponentContextImpl<S>, T>();
+    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
@@ -59,7 +51,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
@@ -67,22 +59,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
@@ -95,7 +85,7 @@ public class MultiplePrototypeRefPair<S,
     public boolean getServiceObject(ComponentContextImpl<S> key, BundleContext 
context,
         SimpleLogger logger)
     {
-       final T service = 
key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef(), 
serviceObjects);
+       final T service = 
key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
         if ( service == null )
         {
             setFailed();
@@ -107,8 +97,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/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
URL: 
http://svn.apache.org/viewvc/felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java?rev=1851459&r1=1851458&r2=1851459&view=diff
==============================================================================
--- 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
 (original)
+++ 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
 Wed Jan 16 15:51:19 2019
@@ -45,11 +45,6 @@ public abstract class RefPair<S, T>
         return ref;
     }
 
-    public ServiceObjects<T> getServiceObjects()
-    {
-        return null;
-    }
-
     public abstract boolean getServiceObject( ComponentContextImpl<S> key, 
BundleContext context, SimpleLogger logger );
 
     public abstract T getServiceObject(ComponentContextImpl<S> key);

Modified: 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
URL: 
http://svn.apache.org/viewvc/felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java?rev=1851459&r1=1851458&r2=1851459&view=diff
==============================================================================
--- 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
 (original)
+++ 
felix/branches/scr-2.0.x/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
 Wed Jan 16 15:51:19 2019
@@ -22,7 +22,6 @@ package org.apache.felix.scr.impl.manage
 
 import org.apache.felix.scr.impl.helper.SimpleLogger;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
@@ -31,18 +30,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
@@ -55,7 +45,7 @@ public class SinglePrototypeRefPair<S, T
     public boolean getServiceObject(ComponentContextImpl<S> key, BundleContext 
context,
         SimpleLogger logger)
     {
-       final T service = 
key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef(), 
serviceObjects);
+       final T service = 
key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
         if ( service == null )
         {
             setFailed();
@@ -67,9 +57,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
+               }
+       }
+    
 }


Reply via email to