Author: davidb
Date: Fri Feb 26 10:56:04 2016
New Revision: 1732453
URL: http://svn.apache.org/viewvc?rev=1732453&view=rev
Log:
FELIX-5199 Race condition in HttpServiceFactory.getService() causing exception
Improved the thread safety of this fix.
Modified:
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
Modified:
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
URL:
http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java?rev=1732453&r1=1732452&r2=1732453&view=diff
==============================================================================
---
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
(original)
+++
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
Fri Feb 26 10:56:04 2016
@@ -139,14 +139,27 @@ public final class HttpServiceFactory
@Override
public HttpService getService(final Bundle bundle, final
ServiceRegistration<HttpService> reg)
{
- if ( active ) {
- return new PerBundleHttpServiceImpl(bundle,
- this.sharedHttpService,
- this.context,
- this.contextAttributeListenerManager,
- this.sharedContextAttributes,
- this.requestListenerManager,
- this.requestAttributeListenerManager);
+ // Only return a service after start() has been called.
+ if (active) {
+ // Store everything that we want to pass to the
PerBundleHttpServiceImpl in local vars to avoid
+ // a race condition where the service might be stopped while this
method is executing.
+ SharedHttpServiceImpl sharedHttpSvc = this.sharedHttpService;
+ ServletContext servletCtx = this.context;
+ ServletContextAttributeListenerManager servletCtxAttrListenerMgr =
this.contextAttributeListenerManager;
+ boolean sharedCtxAttrs = this.sharedContextAttributes;
+ ServletRequestListenerManager reqListenerMgr =
this.requestListenerManager;
+ ServletRequestAttributeListenerManager reqAttrListenerMgr =
this.requestAttributeListenerManager;
+
+ if ( active ) {
+ // Only return the service if we're still active
+ return new PerBundleHttpServiceImpl(bundle,
+ sharedHttpSvc,
+ servletCtx,
+ servletCtxAttrListenerMgr,
+ sharedCtxAttrs,
+ reqListenerMgr,
+ reqAttrListenerMgr);
+ }
}
return null;
}