8049220: URL.factory data race
authorplevart
Wed, 09 Jul 2014 12:30:17 +0200
changeset 25398 f7bdeeb2ca57
parent 25397 26482834c5bc
child 25399 a8ec88e2d76f
8049220: URL.factory data race Reviewed-by: alanb, psandoz
jdk/src/share/classes/java/net/URL.java
--- a/jdk/src/share/classes/java/net/URL.java	Wed Jul 09 16:34:31 2014 +0800
+++ b/jdk/src/share/classes/java/net/URL.java	Wed Jul 09 12:30:17 2014 +0200
@@ -1071,7 +1071,7 @@
     /**
      * The URLStreamHandler factory.
      */
-    static URLStreamHandlerFactory factory;
+    private static volatile URLStreamHandlerFactory factory;
 
     /**
      * Sets an application's {@code URLStreamHandlerFactory}.
@@ -1106,6 +1106,7 @@
                 security.checkSetFactory();
             }
             handlers.clear();
+            // safe publication of URLStreamHandlerFactory with volatile write
             factory = fac;
         }
     }
@@ -1127,9 +1128,11 @@
 
             boolean checkedWithFactory = false;
 
-            // Use the factory (if any)
-            if (factory != null) {
-                handler = factory.createURLStreamHandler(protocol);
+            // Use the factory (if any). Volatile read makes
+            // URLStreamHandlerFactory appear fully initialized to current thread.
+            URLStreamHandlerFactory fac = factory;
+            if (fac != null) {
+                handler = fac.createURLStreamHandler(protocol);
                 checkedWithFactory = true;
             }
 
@@ -1193,8 +1196,8 @@
 
                 // Check with factory if another thread set a
                 // factory since our last check
-                if (!checkedWithFactory && factory != null) {
-                    handler2 = factory.createURLStreamHandler(protocol);
+                if (!checkedWithFactory && (fac = factory) != null) {
+                    handler2 = fac.createURLStreamHandler(protocol);
                 }
 
                 if (handler2 != null) {