You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2010/08/16 17:41:19 UTC
svn commit: r985994 -
/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServicePublisher.java
Author: pderop
Date: Mon Aug 16 15:41:19 2010
New Revision: 985994
URL: http://svn.apache.org/viewvc?rev=985994&view=rev
Log:
fixed a potential race condition in the Service annotation, where a publisher may be invoked before the component is actually started
Modified:
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServicePublisher.java
Modified: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServicePublisher.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServicePublisher.java?rev=985994&r1=985993&r2=985994&view=diff
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServicePublisher.java (original)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServicePublisher.java Mon Aug 16 15:41:19 2010
@@ -93,28 +93,81 @@ public class ServicePublisher
.setDefaultImplementation(unpublisher));
}
}
-
+
+ private void publish()
+ {
+ if (m_published.compareAndSet(false, true))
+ {
+ try
+ {
+ Log.instance().log(LogService.LOG_DEBUG, "publishing services %s",
+ Arrays.toString(m_services));
+ m_registration = m_bc.registerService(m_services, m_srv.getService(), m_srv.getServiceProperties());
+ }
+ catch (Throwable t)
+ {
+ if (t instanceof RuntimeException)
+ {
+ throw (RuntimeException) t;
+ }
+ else
+ {
+ throw new RuntimeException("Could not register services", t);
+ }
+ }
+ }
+ }
+
+ private void unpublish()
+ {
+ if (m_published.compareAndSet(true, false))
+ {
+ try
+ {
+ if (m_registration != null)
+ {
+ Log.instance().log(LogService.LOG_DEBUG, "unpublishing services %s",
+ Arrays.toString(m_services));
+ m_registration.unregister();
+ m_registration = null;
+ }
+ }
+ catch (Throwable t)
+ {
+ if (t instanceof RuntimeException)
+ {
+ throw (RuntimeException) t;
+ }
+ else
+ {
+ throw new RuntimeException("Could not unregister services", t);
+ }
+ }
+ }
+ }
+
private class Publisher implements Runnable, ServiceStateListener
{
- private boolean m_started; // true if the service has started
-
+ // true if the service has started
+ private boolean m_started;
+ // flag used to delay early publisher until we are really started.
+ public boolean m_publishDelayed;
+
public void run()
{
- if (m_published.compareAndSet(false, true))
- {
- // Only register the service if it has been started. Otherwise delay the registration
- // until the service start callback has been invoked.
- synchronized (this) {
- if (! m_started)
- {
- Log.instance().log(LogService.LOG_DEBUG, "Delaying service publication for services %s (service not yet started)",
- Arrays.toString(m_services));
+ // Only register the service if it has been started. Otherwise delay the registration
+ // until the service start callback has been invoked.
+ synchronized (this) {
+ if (! m_started)
+ {
+ Log.instance().log(LogService.LOG_DEBUG, "Delaying service publication for services %s (service not yet started)",
+ Arrays.toString(m_services));
- return;
- }
+ m_publishDelayed = true;
+ return;
}
- publish();
}
+ publish();
}
public void starting(Service service)
@@ -123,11 +176,16 @@ public class ServicePublisher
public void started(Service service)
{
+ boolean publishDelayed = false;
synchronized (this)
{
m_started = true;
+ if (m_publishDelayed)
+ {
+ publishDelayed = true;
+ }
}
- if (m_published.get())
+ if (publishDelayed)
{
// Our runnable has been invoked before the service start callback has been called:
// Now that we are started, we fire the service registration.
@@ -140,62 +198,21 @@ public class ServicePublisher
synchronized (this)
{
m_started = false;
+ m_publishDelayed = false;
}
-
- if (m_published.compareAndSet(true, false))
- {
- if (m_registration != null)
- {
- Log.instance().log(LogService.LOG_DEBUG, "unpublishing services %s (service is stopping)",
- Arrays.toString(m_services));
-
- m_registration.unregister();
- m_registration = null;
- }
- }
+ unpublish();
}
public void stopped(Service service)
{
- }
-
- private void publish()
- {
- try
- {
- Log.instance().log(LogService.LOG_DEBUG, "publishing services %s",
- Arrays.toString(m_services));
- m_registration = m_bc.registerService(m_services, m_srv.getService(), m_srv.getServiceProperties());
- }
- catch (Throwable t)
- {
- m_published.set(false);
- if (t instanceof RuntimeException)
- {
- throw (RuntimeException) t;
- }
- else
- {
- throw new RuntimeException("Could not register services", t);
- }
- }
- }
+ }
}
private class Unpublisher implements Runnable
{
public void run()
{
- if (m_published.compareAndSet(true, false))
- {
- if (m_registration != null)
- {
- Log.instance().log(LogService.LOG_DEBUG, "unpublishing services %s",
- Arrays.toString(m_services));
- m_registration.unregister();
- m_registration = null;
- }
- }
+ unpublish();
}
}
}