Defensive approach when releasing the read lock.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1493380 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
index 7f4996d..1b623b9 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
@@ -600,7 +600,11 @@
* @return {@literal true} if the lock has no more holders, {@literal false} otherwise.
*/
public boolean releaseReadLockIfHeld() {
- m_lock.readLock().unlock();
+ try {
+ m_lock.readLock().unlock();
+ } catch (IllegalMonitorStateException e) {
+ // Oupsy we were not holding the lock...
+ }
return true;
}
@@ -1062,20 +1066,22 @@
}
}
- // Leaving the locked region to invoke callbacks, but grab the read lock
+ // Before leaving the protected region, copy used services.
+ Map<ServiceReference, Object> services = new HashMap<ServiceReference, Object>(m_serviceObjects);
+
+ // Leaving the locked region to invoke callbacks
releaseWriteLockIfHeld();
- try {
- acquireReadLockIfNotHeld();
+
for (ServiceReference ref : departures) {
onServiceDeparture(ref);
// Notify service unbinding to listeners
- Object svc = m_serviceObjects.get(ref);
+ Object svc = services.get(ref);
notifyListeners(DependencyEventType.UNBINDING, ref, svc);
}
for (ServiceReference ref : arrivals) {
onServiceArrival(ref);
// Notify service binding to listeners
- Object svc = m_serviceObjects.get(ref);
+ Object svc = services.get(ref);
notifyListeners(DependencyEventType.BINDING, ref, svc);
}
// Do we have a modified service ?
@@ -1083,9 +1089,6 @@
onServiceModification(set.modified);
// TODO call boundServiceModified on listeners???
}
- } finally {
- releaseReadLockIfHeld();
- }
// Did our state changed ?
// this method will manage its own synchronization.