You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2016/03/22 11:52:16 UTC
svn commit: r1736182 - in
/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers:
ResourceProviderHandler.java ResourceProviderTracker.java
Author: cziegeler
Date: Tue Mar 22 10:52:16 2016
New Revision: 1736182
URL: http://svn.apache.org/viewvc?rev=1736182&view=rev
Log:
SLING-5622 : Deadlock between service unregister (thus unbindTopologyEventListener) and discoveryLiteCheck
Modified:
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderHandler.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTracker.java
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderHandler.java?rev=1736182&r1=1736181&r2=1736182&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderHandler.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderHandler.java Tue Mar 22 10:52:16 2016
@@ -38,6 +38,8 @@ public class ResourceProviderHandler imp
private volatile boolean isUsed = false;
+ private volatile long activationCount;
+
public ResourceProviderHandler(final BundleContext bc, final ResourceProviderInfo info) {
this.info = info;
this.bundleContext = bc;
@@ -49,14 +51,26 @@ public class ResourceProviderHandler imp
@SuppressWarnings("unchecked")
public boolean activate() {
- this.provider = (ResourceProvider<Object>) this.bundleContext.getService(this.info.getServiceReference());
- if ( this.provider != null ) {
- this.provider.start(context);
+ this.activationCount++;
+ if ( this.provider == null ) {
+ this.provider = (ResourceProvider<Object>) this.bundleContext.getService(this.info.getServiceReference());
+ if ( this.provider != null ) {
+ this.provider.start(context);
+ }
}
return this.provider != null;
}
- /**C
+ public void deactivate() {
+ if ( this.provider != null ) {
+ this.provider.stop();
+ this.provider = null;
+ this.context.update(null, null);
+ this.bundleContext.ungetService(this.info.getServiceReference());
+ }
+ }
+
+ /**
* Clear all references.
*/
public void dispose() {
@@ -66,6 +80,10 @@ public class ResourceProviderHandler imp
this.isUsed = false;
}
+ public long getActivationCount() {
+ return this.activationCount;
+ }
+
public ResourceProvider<Object> getResourceProvider() {
return this.provider;
}
@@ -79,15 +97,6 @@ public class ResourceProviderHandler imp
return this.isUsed;
}
- public void deactivate() {
- if ( this.provider != null ) {
- this.provider.stop();
- this.provider = null;
- this.context.update(null, null);
- this.bundleContext.ungetService(this.info.getServiceReference());
- }
- }
-
@Override
public int compareTo(final ResourceProviderHandler o) {
if ( this.getInfo() == null ) {
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTracker.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTracker.java?rev=1736182&r1=1736181&r2=1736182&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTracker.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTracker.java Tue Mar 22 10:52:16 2016
@@ -163,6 +163,10 @@ public class ResourceProviderTracker imp
if ( info.isValid() ) {
logger.debug("Registering new resource provider {}", info);
final List<ProviderEvent> events = new ArrayList<ResourceProviderTracker.ProviderEvent>();
+ boolean providerAdded = false;
+ ResourceProviderHandler deactivateHandler = null;
+ long deactivateHandlerCount = 0;
+
synchronized ( this.handlers ) {
List<ResourceProviderHandler> matchingHandlers = this.handlers.get(info.getPath());
if ( matchingHandlers == null ) {
@@ -179,26 +183,36 @@ public class ResourceProviderTracker imp
this.handlers.remove(info.getPath());
}
} else {
- final ChangeListener cl = this.listener;
- if ( cl != null ) {
- cl.providerAdded();
- }
+ providerAdded = true;
events.add(new ProviderEvent(true, info));
if ( matchingHandlers.size() > 1 ) {
- final ResourceProviderHandler removeHandler = matchingHandlers.get(1);
- final ResourceProviderInfo removeInfo = removeHandler.getInfo();
- if ( cl != null ) {
- cl.providerRemoved((String)removeInfo.getServiceReference().getProperty(Constants.SERVICE_PID),
- removeInfo.getAuthType() != AuthType.no,
- removeHandler.isUsed());
- }
- this.deactivate(removeHandler);
- events.add(new ProviderEvent(false, removeInfo));
+ deactivateHandler = matchingHandlers.get(1);
+ deactivateHandlerCount = deactivateHandler.getActivationCount();
}
+ storage = null;
+ }
+ }
+ }
+ final ChangeListener cl = this.listener;
+ if ( providerAdded && cl != null ) {
+ cl.providerAdded();
+ }
+ // we have to check for deactivated handlers
+ if ( deactivateHandler != null ) {
+ final ResourceProviderInfo handlerInfo = deactivateHandler.getInfo();
+ if ( cl != null ) {
+ cl.providerRemoved((String)handlerInfo.getServiceReference().getProperty(Constants.SERVICE_PID),
+ handlerInfo.getAuthType() != AuthType.no,
+ deactivateHandler.isUsed());
+ }
+ synchronized ( this.handlers ) {
+ if ( deactivateHandlerCount == deactivateHandler.getActivationCount() ) {
+ this.deactivate(deactivateHandler);
+ events.add(new ProviderEvent(false, handlerInfo));
+ storage = null;
}
}
}
- this.storage = null;
this.postEvents(events);
} else {
logger.warn("Ignoring invalid resource provider {}", info);
@@ -219,31 +233,39 @@ public class ResourceProviderTracker imp
if ( !isInvalid ) {
logger.debug("Unregistering resource provider {}", info);
final List<ProviderEvent> events = new ArrayList<ResourceProviderTracker.ProviderEvent>();
+ ResourceProviderHandler deactivateHandler = null;
synchronized (this.handlers) {
final List<ResourceProviderHandler> matchingHandlers = this.handlers.get(info.getPath());
if ( matchingHandlers != null ) {
- boolean doActivateNext = false;
final ResourceProviderHandler firstHandler = matchingHandlers.get(0);
if ( firstHandler.getInfo() == info ) {
- doActivateNext = true;
- final ChangeListener cl = this.listener;
- if ( cl != null ) {
- cl.providerRemoved(pid,
- info.getAuthType() != AuthType.no,
- firstHandler.isUsed());
- }
- this.deactivate(firstHandler);
- events.add(new ProviderEvent(false, firstHandler.getInfo()));
+ deactivateHandler = firstHandler;
+
}
+ }
+ }
+ if ( deactivateHandler != null ) {
+ final ChangeListener cl = this.listener;
+ if ( cl != null ) {
+ cl.providerRemoved(pid,
+ info.getAuthType() != AuthType.no,
+ deactivateHandler.isUsed());
+ }
+ boolean providerAdded = false;
+ synchronized ( this.handlers ) {
+ this.deactivate(deactivateHandler);
+ storage = null;
+
+ final List<ResourceProviderHandler> matchingHandlers = this.handlers.get(info.getPath());
+ final ResourceProviderHandler firstHandler = matchingHandlers.get(0);
+ boolean doActivateNext = firstHandler.getInfo() == info;
+
if (removeHandlerByInfo(info, matchingHandlers)) {
while (doActivateNext && !matchingHandlers.isEmpty()) {
if (this.activate(matchingHandlers.get(0))) {
doActivateNext = false;
events.add(new ProviderEvent(true, matchingHandlers.get(0).getInfo()));
- final ChangeListener cl = this.listener;
- if ( cl != null ) {
- cl.providerAdded();
- }
+ providerAdded = true;
} else {
matchingHandlers.remove(0);
}
@@ -253,8 +275,14 @@ public class ResourceProviderTracker imp
this.handlers.remove(info.getPath());
}
}
+ if ( providerAdded && cl != null ) {
+ if ( cl != null ) {
+ cl.providerAdded();
+ }
+ }
+ events.add(new ProviderEvent(false,info));
+
}
- storage = null;
this.postEvents(events);
} else {
logger.debug("Unregistering invalid resource provider {}", info);