You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ma...@apache.org on 2010/10/14 16:40:32 UTC

svn commit: r1022549 - /felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java

Author: marrs
Date: Thu Oct 14 14:40:32 2010
New Revision: 1022549

URL: http://svn.apache.org/viewvc?rev=1022549&view=rev
Log:
Fixed a concurrent modification exception caused by improper and missing synchronization.

Modified:
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java?rev=1022549&r1=1022548&r2=1022549&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/tracker/ServiceTracker.java Thu Oct 14 14:40:32 2010
@@ -810,7 +810,10 @@ public class ServiceTracker implements S
 	 * @ThreadSafe
 	 */
 	class Tracked extends AbstractTracked implements ServiceListener {
-	    /** A list of services that are currently hidden because there is an aspect available with a higher ranking. */
+	    /**
+	     * A list of services that are currently hidden because there is an aspect available with a higher ranking.
+	     * @GuardedBy this
+	     */
 	    private final List m_hidden = new ArrayList();
 	    
 	    /**
@@ -822,7 +825,7 @@ public class ServiceTracker implements S
 	    private ServiceReference highestHidden(long serviceId) {
 	        ServiceReference result = null;
 	        int max = Integer.MIN_VALUE;
-	        synchronized (m_hidden) {
+	        synchronized (this) {
     	        for (int i = 0; i < m_hidden.size(); i++) {
     	            ServiceReference ref = (ServiceReference) m_hidden.get(i);
     	            Long sid = (Long) ref.getProperty(Constants.SERVICE_ID);
@@ -853,25 +856,32 @@ public class ServiceTracker implements S
         private ServiceReference highestTracked(long serviceId) {
             ServiceReference result = null;
             int max = Integer.MIN_VALUE;
-            Object[] trackedServices = getTracked(new Object[] {});
-            for (int i = 0; i < trackedServices.length; i++) {
-                ServiceReference ref = (ServiceReference) trackedServices[i];
-                Long sid = (Long) ref.getProperty(Constants.SERVICE_ID);
-                Long aid = (Long) ref.getProperty(DependencyManager.ASPECT);
-                if ((aid != null && aid.longValue() == serviceId) 
-                    || (aid == null && sid != null && sid.longValue() == serviceId)) {
-                    Integer ranking = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
-                    int r = 0;
-                    if (ranking != null) {
-                        r = ranking.intValue();
-                    }
-                    if (r > max) {
-                        max = r;
-                        result = ref;
+            
+            synchronized (this) {
+                int length = size();
+                if (length == 0) {
+                    return null;
+                }
+                Object[] trackedServices = getTracked(new ServiceReference[length]);
+                for (int i = 0; i < trackedServices.length; i++) {
+                    ServiceReference ref = (ServiceReference) trackedServices[i];
+                    Long sid = (Long) ref.getProperty(Constants.SERVICE_ID);
+                    Long aid = (Long) ref.getProperty(DependencyManager.ASPECT);
+                    if ((aid != null && aid.longValue() == serviceId) 
+                        || (aid == null && sid != null && sid.longValue() == serviceId)) {
+                        Integer ranking = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
+                        int r = 0;
+                        if (ranking != null) {
+                            r = ranking.intValue();
+                        }
+                        if (r > max) {
+                            max = r;
+                            result = ref;
+                        }
                     }
                 }
+                return result;
             }
-            return result;
         }
 
         /**
@@ -881,7 +891,7 @@ public class ServiceTracker implements S
          */
         private void hide(ServiceReference ref) {
             if (DEBUG) { System.out.println("ServiceTracker.Tracked.hide " + ServiceUtil.toString(ref)); }
-            synchronized (m_hidden) {
+            synchronized (this) {
                 if (DEBUG) { if (m_hidden.contains(ref)) { System.out.println("ServiceTracker.Tracked.hide ERROR: " + ServiceUtil.toString(ref)); }};
                 m_hidden.add(ref);
             }
@@ -894,7 +904,7 @@ public class ServiceTracker implements S
          */
         private void unhide(ServiceReference ref) {
             if (DEBUG) { System.out.println("ServiceTracker.Tracked.unhide " + ServiceUtil.toString(ref)); }
-            synchronized (m_hidden) {
+            synchronized (this) {
                 if (DEBUG) { if (!m_hidden.contains(ref)) { System.out.println("ServiceTracker.Tracked.unhide ERROR: " + ServiceUtil.toString(ref)); }};
                 m_hidden.remove(ref);
             }