8023541: Race condition in rmid initialization
authorsmarks
Thu, 30 Jan 2014 15:12:38 -0800
changeset 22619 28616839f0dd
parent 22618 927e4fe6cb24
child 22620 3a49604673ae
8023541: Race condition in rmid initialization Reviewed-by: alanb, dfuchs, dholmes, plevart, psandoz, tyan
jdk/src/share/classes/sun/rmi/server/Activation.java
--- a/jdk/src/share/classes/sun/rmi/server/Activation.java	Thu Jan 30 09:15:13 2014 -0800
+++ b/jdk/src/share/classes/sun/rmi/server/Activation.java	Thu Jan 30 15:12:38 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -299,7 +299,7 @@
 
         private static final String NAME = ActivationSystem.class.getName();
         private static final long serialVersionUID = 4877330021609408794L;
-        private final ActivationSystem systemStub;
+        private ActivationSystem systemStub = null;
 
         SystemRegistryImpl(int port,
                            RMIClientSocketFactory csf,
@@ -308,7 +308,39 @@
             throws RemoteException
         {
             super(port, csf, ssf);
-            this.systemStub = systemStub;
+            assert systemStub != null;
+            synchronized (this) {
+                this.systemStub = systemStub;
+                notifyAll();
+            }
+        }
+
+        /**
+         * Waits for systemStub to be initialized and returns its
+         * initialized value. Any remote call that uses systemStub must
+         * call this method to get it instead of using direct field
+         * access. This is necessary because the super() call in the
+         * constructor exports this object before systemStub is initialized
+         * (see JDK-8023541), allowing remote calls to come in during this
+         * time. We can't use checkShutdown() like other nested classes
+         * because this is a static class.
+         */
+        private synchronized ActivationSystem getSystemStub() {
+            boolean interrupted = false;
+
+            while (systemStub == null) {
+                try {
+                    wait();
+                } catch (InterruptedException ie) {
+                    interrupted = true;
+                }
+            }
+
+            if (interrupted) {
+                Thread.currentThread().interrupt();
+            }
+
+            return systemStub;
         }
 
         /**
@@ -321,7 +353,7 @@
             throws RemoteException, NotBoundException
         {
             if (name.equals(NAME)) {
-                return systemStub;
+                return getSystemStub();
             } else {
                 return super.lookup(name);
             }