FELIX-1239 Do not make the AbstractComponentManager.getServiceReference method synchronized
and document how we cope with multi-threading situations. Also make the serviceReference field
volatile to help us here.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@784722 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java
index 38fe9eb..2954dbc 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java
@@ -47,6 +47,8 @@
private long m_componentId;
// The state of this instance manager
+ // methods accessing this field should be synchronized unless there is a
+ // good reason to not be synchronized
private volatile State m_state;
// The metadata
@@ -59,7 +61,7 @@
private BundleComponentActivator m_activator;
// The ServiceRegistration
- private ServiceRegistration m_serviceRegistration;
+ private volatile ServiceRegistration m_serviceRegistration;
/**
* There are 9 states in all. They are: Disabled, Enabled, Unsatisfied,
@@ -619,9 +621,29 @@
m_state.disposeInternal( this );
}
- synchronized final ServiceReference getServiceReference()
+
+ final ServiceReference getServiceReference()
{
- return m_state.getServiceReference( this );
+ // This method is not synchronized even though it accesses the state.
+ // The reason for this is that we just want to have the state return
+ // the service reference which comes from the service registration.
+ // The only thing that may happen is that the service registration is
+ // still set on this instance but the service has already been
+ // unregistered. In this case an IllegalStateException may be thrown
+ // which we just catch and ignore returning null
+ State state = m_state;
+ try
+ {
+ return state.getServiceReference( this );
+ }
+ catch ( IllegalStateException ise )
+ {
+ // may be thrown if the service has already been unregistered but
+ // the service registration is still set on this component manager
+ // we ignore this exception and assume there is no service reference
+ }
+
+ return null;
}
//---------- Component handling methods ----------------------------------