You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by tj...@apache.org on 2019/02/05 16:23:06 UTC
svn commit: r1853021 - in
/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl: helper/ manager/
Author: tjwatson
Date: Tue Feb 5 16:23:06 2019
New Revision: 1853021
URL: http://svn.apache.org/viewvc?rev=1853021&view=rev
Log:
FELIX-6044 - Fixes for maintaining correct reference usage
- unget non-prototype service refs
- avoid creating multiple prototype instances for same component
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/SingleComponentManager.java
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SinglePrototypeRefPair.java
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.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=1853021&r1=1853020&r2=1853021&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 Tue Feb 5 16:23:06 2019
@@ -41,6 +41,8 @@ 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;
@@ -63,6 +65,7 @@ public class ComponentServiceObjectsHelp
{
cso.deactivate();
}
+ prototypeInstances.clear();
}
public ComponentServiceObjects getServiceObjects(final ServiceReference<?> ref)
@@ -98,7 +101,19 @@ public class ComponentServiceObjectsHelp
public <T> T getPrototypeRefInstance(final ServiceReference<T> ref)
{
- return (T) getServiceObjects(ref).getService();
+ T service = (T) prototypeInstances.get(ref);
+ if ( service == null )
+ {
+ service = (T) getServiceObjects(ref).getService();
+ T oldService = (T)prototypeInstances.putIfAbsent(ref, service);
+ if ( oldService != null )
+ {
+ // another thread created the instance already
+ getServiceObjects(ref).ungetService(service);
+ service = oldService;
+ }
+ }
+ return service;
}
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=1853021&r1=1853020&r2=1853021&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 Tue Feb 5 16:23:06 2019
@@ -223,15 +223,7 @@ public class DependencyManager<S, T> imp
protected void ungetService(RefPair<S, T> ref)
{
- Object service = ref.unsetServiceObject(null);
- if (service != null)
- {
- BundleContext bundleContext = m_componentManager.getBundleContext();
- if (bundleContext != null)
- {
- bundleContext.ungetService(ref.getRef());
- }
- }
+ ref.ungetServiceObjects(m_componentManager.getBundleContext());
}
protected void tracked(int trackingCount)
@@ -1690,7 +1682,7 @@ public class DependencyManager<S, T> imp
invokeUnbindMethod(componentContext, boundRef, trackingCount.get(), edgeInfo);
}
- boundRef.unsetServiceObject(componentContext);
+ boundRef.ungetServiceObject(componentContext);
}
latch.countDown();
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=1853021&r1=1853020&r2=1853021&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 Tue Feb 5 16:23:06 2019
@@ -54,7 +54,7 @@ public class MultiplePrototypeRefPair<S,
}
@Override
- public T unsetServiceObject(ComponentContextImpl<S> key)
+ public T ungetServiceObject(ComponentContextImpl<S> key)
{
if ( key == null )
{
@@ -75,6 +75,11 @@ public class MultiplePrototypeRefPair<S,
}
@Override
+ public void ungetServiceObjects(BundleContext bundleContext) {
+ ungetServiceObject(null);
+ }
+
+ @Override
public String toString()
{
return "[MultiplePrototypeRefPair: ref: [" + getRef() + "] has service: [" + !instances.isEmpty() + "]]";
@@ -83,7 +88,7 @@ public class MultiplePrototypeRefPair<S,
@Override
public boolean getServiceObject(ComponentContextImpl<S> key, BundleContext context)
{
- final T service = key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
+ final T service = key.getComponentServiceObjectsHelper().getPrototypeRefInstance(this.getRef());
if ( service == null )
{
setFailed();
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=1853021&r1=1853020&r2=1853021&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 Tue Feb 5 16:23:06 2019
@@ -50,7 +50,8 @@ public abstract class RefPair<S, T>
public abstract boolean setServiceObject( ComponentContextImpl<S> key, T serviceObject );
- public abstract T unsetServiceObject(ComponentContextImpl<S> key);
+ public abstract void ungetServiceObjects(BundleContext context);
+ public abstract T ungetServiceObject(ComponentContextImpl<S> key);
public void setFailed( )
{
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java?rev=1853021&r1=1853020&r2=1853021&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java Tue Feb 5 16:23:06 2019
@@ -161,7 +161,6 @@ public class SingleComponentManager<S> e
{
m_useCount.set( 0 );
disposeImplementationObject( m_componentContext, reason );
- m_componentContext.cleanup();
m_componentContext = null;
getLogger().log( LogService.LOG_DEBUG, "Unset and deconfigured implementation object for component in deleteComponent for reason {0}", null, REASONS[ reason ] );
clearServiceProperties();
@@ -417,7 +416,7 @@ public class SingleComponentManager<S> e
md.close( componentContext, componentContext.getEdgeInfo( md ) );
}
}
-
+ componentContext.cleanup();
}
@Override
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=1853021&r1=1853020&r2=1853021&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 Tue Feb 5 16:23:06 2019
@@ -20,6 +20,8 @@
package org.apache.felix.scr.impl.manager;
+import java.util.concurrent.atomic.AtomicReference;
+
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogService;
@@ -27,14 +29,56 @@ import org.osgi.service.log.LogService;
/**
* @version $Rev$ $Date$
*/
-public class SinglePrototypeRefPair<S, T> extends SingleRefPair<S, T>
+public class SinglePrototypeRefPair<S, T> extends RefPair<S, T>
{
+ class SingleKeyService {
+ final ComponentContextImpl<S> key;
+ final T serviceObject;
+ SingleKeyService(ComponentContextImpl<S> key, T serviceObject) {
+ this.key = key;
+ this.serviceObject = serviceObject;
+ }
+ }
+ protected AtomicReference<SingleKeyService> serviceObjectRef = new AtomicReference<>();
+
public SinglePrototypeRefPair( ServiceReference<T> ref )
{
super(ref);
}
@Override
+ public T getServiceObject(ComponentContextImpl<S> key)
+ {
+ SingleKeyService service = serviceObjectRef.get();
+ return service == null ? null : service.serviceObject;
+ }
+
+ @Override
+ public boolean setServiceObject(ComponentContextImpl<S> key, T serviceObject)
+ {
+ return serviceObjectRef.compareAndSet(null, new SingleKeyService(key, serviceObject ));
+ }
+
+ @Override
+ public T ungetServiceObject(ComponentContextImpl<S> key)
+ {
+ SingleKeyService service = serviceObjectRef.getAndSet(null);
+ if (service != null) {
+ if (key == null) {
+ key = service.key;
+ }
+ doUngetService(key, service.serviceObject);
+ return service.serviceObject;
+ }
+ return null;
+ }
+
+ @Override
+ public void ungetServiceObjects(BundleContext bundleContext) {
+ ungetServiceObject(null);
+ }
+
+ @Override
public String toString()
{
return "[SinglePrototypeRefPair: ref: [" + getRef() + "] service: [" + getServiceObject(null) + "]]";
@@ -49,37 +93,25 @@ public class SinglePrototypeRefPair<S, T
setFailed();
key.getLogger().log(
LogService.LOG_WARNING,
- "Could not get service from serviceobjects for ref {0}",null, getRef() );
+ "Could not get service from serviceobjects for ref {0}", null, getRef() );
return false;
}
if (!setServiceObject(key, service))
{
// Another thread got the service before, so unget our
- doUngetService(key, 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);
+ key.getComponentServiceObjectsHelper().getServiceObjects(getRef()).ungetService( service );
}
- catch (final IllegalStateException ise)
+ catch ( final IllegalStateException ise )
{
// ignore
}
}
-
}
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java?rev=1853021&r1=1853020&r2=1853021&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleRefPair.java Tue Feb 5 16:23:06 2019
@@ -31,7 +31,7 @@ import org.osgi.service.log.LogService;
*/
public class SingleRefPair<S, T> extends RefPair<S, T>
{
- private AtomicReference<T> serviceObjectRef = new AtomicReference<>();
+ protected AtomicReference<T> serviceObjectRef = new AtomicReference<>();
public SingleRefPair( ServiceReference<T> ref )
{
@@ -56,9 +56,22 @@ public class SingleRefPair<S, T> extends
}
@Override
- public T unsetServiceObject(ComponentContextImpl<S> key)
+ public T ungetServiceObject(ComponentContextImpl<S> key) {
+ // null operation for singleRefPair
+ return null;
+ }
+
+ @Override
+ public void ungetServiceObjects(BundleContext bundleContext)
{
- return serviceObjectRef.getAndSet( null );
+ T service = serviceObjectRef.getAndSet( null );
+ if (service != null)
+ {
+ if (bundleContext != null)
+ {
+ bundleContext.ungetService(getRef());
+ }
+ }
}
@Override