Author: jwross
Date: Wed Apr 17 11:40:11 2013
New Revision: 1468845

URL: http://svn.apache.org/r1468845
Log:
Fix potential deadlock when propagating subsystem service events.

Modified:
    
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java

Modified: 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java?rev=1468845&r1=1468844&r2=1468845&view=diff
==============================================================================
--- 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java
 (original)
+++ 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java
 Wed Apr 17 11:40:11 2013
@@ -19,7 +19,6 @@ import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.aries.subsystem.AriesSubsystem;
@@ -39,19 +38,23 @@ public class SubsystemServiceRegistrar {
                this.context = context;
        }
        
-       public synchronized void addRegion(BasicSubsystem subsystem, Region 
region) {
-               ServiceRegistration<?> registration = map.get(subsystem);
-               if (registration == null)
-                       throw new IllegalStateException("Subsystem '" + 
subsystem + "' is not registered");
-               Collection<String> currentRegions = 
(Collection<String>)registration.getReference().getProperty(Constants.SubsystemServicePropertyRegions);
-               String regionName = region.getName();
-               if (currentRegions.contains(regionName))
-                       return;
-               Collection<String> newRegions = new 
HashSet<String>(currentRegions.size() + 1);
-               newRegions.addAll(currentRegions);
-               newRegions.add(regionName);
-               Dictionary<String, Object> properties = properties(subsystem);
-               properties.put(Constants.SubsystemServicePropertyRegions, 
Collections.unmodifiableCollection(newRegions));
+       public void addRegion(BasicSubsystem subsystem, Region region) {
+               ServiceRegistration<?> registration;
+               Dictionary<String, Object> properties;
+               synchronized (this) {
+                       registration = map.get(subsystem);
+                       if (registration == null)
+                               throw new IllegalStateException("Subsystem '" + 
subsystem + "' is not registered");
+                       Collection<String> currentRegions = 
(Collection<String>)registration.getReference().getProperty(Constants.SubsystemServicePropertyRegions);
+                       String regionName = region.getName();
+                       if (currentRegions.contains(regionName))
+                               return;
+                       Collection<String> newRegions = new 
HashSet<String>(currentRegions.size() + 1);
+                       newRegions.addAll(currentRegions);
+                       newRegions.add(regionName);
+                       properties = properties(subsystem);
+                       
properties.put(Constants.SubsystemServicePropertyRegions, 
Collections.unmodifiableCollection(newRegions));
+               }
                registration.setProperties(properties);
        }
        
@@ -62,51 +65,68 @@ public class SubsystemServiceRegistrar {
                return 
(Subsystem)Activator.getInstance().getBundleContext().getService(registration.getReference());
        }
        
-       public synchronized void register(BasicSubsystem child, BasicSubsystem 
parent) {
-               if (map.containsKey(child))
-                       return;
-               Dictionary<String, Object> properties = properties(child, 
parent);
-               ServiceRegistration<?> registration = context.registerService(
+       public void register(BasicSubsystem child, BasicSubsystem parent) {
+               Dictionary<String, Object> properties;
+               synchronized (this) {
+                       if (map.containsKey(child))
+                               return;
+                       map.put(child, null);
+                       properties = properties(child, parent);
+               }
+               ServiceRegistration<?> registration = null;
+               try {
+                       registration = context.registerService(
                                new String[] {Subsystem.class.getName(), 
AriesSubsystem.class.getName()}, 
                                child, properties);
-               map.put(child, registration);
+               }
+               finally {
+                       synchronized (this) {
+                               if (registration == null)
+                                       map.remove(child);
+                               else
+                                       map.put(child, registration);
+                       }
+               }
        }
        
-       public synchronized void removeRegion(BasicSubsystem subsystem, Region 
region) {
-               ServiceRegistration<?> registration = map.get(subsystem);
-               if (registration == null)
-                       return;
-               Collection<String> regions = 
(Collection<String>)registration.getReference().getProperty(Constants.SubsystemServicePropertyRegions);
-               String regionName = region.getName();
-               if (regions == null || !regions.contains(regionName))
-                       return;
-               regions = new HashSet<String>(regions);
-               regions.remove(regionName);
-               Dictionary<String, Object> properties = properties(subsystem);
-               properties.put(Constants.SubsystemServicePropertyRegions, 
Collections.unmodifiableCollection(regions));
+       public void removeRegion(BasicSubsystem subsystem, Region region) {
+               ServiceRegistration<?> registration;
+               Dictionary<String, Object> properties;
+               synchronized (this) {
+                       registration = map.get(subsystem);
+                       if (registration == null)
+                               return;
+                       Collection<String> regions = 
(Collection<String>)registration.getReference().getProperty(Constants.SubsystemServicePropertyRegions);
+                       String regionName = region.getName();
+                       if (regions == null || !regions.contains(regionName))
+                               return;
+                       regions = new HashSet<String>(regions);
+                       regions.remove(regionName);
+                       properties = properties(subsystem);
+                       
properties.put(Constants.SubsystemServicePropertyRegions, 
Collections.unmodifiableCollection(regions));
+               }
                registration.setProperties(properties);
        }
        
-       public synchronized void unregister(Subsystem subsystem) {
-               ServiceRegistration<?> registration = map.remove(subsystem);
-               if (registration == null)
-                       throw new IllegalStateException("Subsystem '" + 
subsystem + "' is not registered");
+       public void unregister(Subsystem subsystem) {
+               ServiceRegistration<?> registration;
+               synchronized (this) {
+                       registration = map.remove(subsystem);
+                       if (registration == null)
+                               throw new IllegalStateException("Subsystem '" + 
subsystem + "' is not registered");
+               }
                registration.unregister();
        }
        
-       public synchronized void unregisterAll() {
-               for (Iterator<ServiceRegistration<?>> i = 
map.values().iterator(); i.hasNext();) {
-                       ServiceRegistration<?> registration = i.next();
-                       registration.unregister();
-                       i.remove();
+       public void update(BasicSubsystem subsystem) {
+               ServiceRegistration<?> registration;
+               Dictionary<String, Object> properties;
+               synchronized (this) {
+                       registration = map.get(subsystem);
+                       if (registration == null)
+                               throw new IllegalStateException("Subsystem '" + 
subsystem + "' is not registered");
+                       properties = properties(subsystem, registration);
                }
-       }
-       
-       public synchronized void update(BasicSubsystem subsystem) {
-               ServiceRegistration<?> registration = map.get(subsystem);
-               if (registration == null)
-                       throw new IllegalStateException("Subsystem '" + 
subsystem + "' is not registered");
-               Dictionary<String, Object> properties = properties(subsystem, 
registration);
                registration.setProperties(properties);
        }
        


Reply via email to