incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmesc...@apache.org
Subject svn commit: r992946 - /sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ServiceCache.java
Date Mon, 06 Sep 2010 06:14:07 GMT
Author: fmeschbe
Date: Mon Sep  6 06:14:07 2010
New Revision: 992946

URL: http://svn.apache.org/viewvc?rev=992946&view=rev
Log:
SLING-1728 Apply version 2 of the patch to prevent potential deadlock

Modified:
    sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ServiceCache.java

Modified: sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ServiceCache.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ServiceCache.java?rev=992946&r1=992945&r2=992946&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ServiceCache.java
(original)
+++ sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ServiceCache.java
Mon Sep  6 06:14:07 2010
@@ -49,7 +49,7 @@ public class ServiceCache implements Ser
 
     public void dispose() {
         this.bundleContext.removeServiceListener(this);
-        for(final Reference ref : cache.values()) {
+        for (final Reference ref : cache.values()) {
             if ( ref != NULL_REFERENCE ) {
                 this.bundleContext.ungetService(ref.reference);
             }
@@ -66,33 +66,44 @@ public class ServiceCache implements Ser
     public <ServiceType> ServiceType getService(Class<ServiceType> type) {
         final String key = type.getName();
         Reference reference = this.cache.get(key);
-        if (reference == null ) {
-            // if the service is not in the cache, we have to go into a synchronized
-            // block to avoid concurrent gets of the same service
+        if (reference == null) {
+
+            // get the service
+            ServiceReference ref = this.bundleContext.getServiceReference(key);
+            if (ref != null) {
+                final Object service = this.bundleContext.getService(ref);
+                if (service != null) {
+                    reference = new Reference();
+                    reference.service = service;
+                    reference.reference = ref;
+                } else {
+                    ref = null;
+                }
+            }
+
+            // assume missing service
+            if (reference == null) {
+                reference = NULL_REFERENCE;
+            }
+
+            // check to see whether another thread has not done the same thing
             synchronized (this) {
-                reference = this.cache.get(key);
-                if ( reference == null ) {
-                    // try to get service from bundle context
-                    final ServiceReference ref = this.bundleContext.getServiceReference(key);
-                    if (ref != null) {
-                        final Object service = this.bundleContext.getService(ref);
-                        if ( service != null ) {
-                            reference = new Reference();
-                            reference.service = service;
-                            reference.reference = ref;
-                        }
-                    }
-                    if ( reference == null ) {
-                        reference = NULL_REFERENCE;
-                    }
+                Reference existing = this.cache.get(key);
+                if (existing == null) {
                     this.cache.put(key, reference);
+                    ref = null;
+                } else {
+                    reference = existing;
                 }
             }
 
+            // unget the service if another thread was faster
+            if (ref != null) {
+                this.bundleContext.ungetService(ref);
+            }
         }
-        if ( reference == NULL_REFERENCE ) {
-            return null;
-        }
+
+        // return whatever we got (which may be null)
         return (ServiceType) reference.service;
     }
 



Mime
View raw message