changeset 22732:677b1d02cb0d

fixed deadlock between JVMCI and TTY initialization (GRAAL-1280)
author Doug Simon <doug.simon@oracle.com>
date Wed, 30 Sep 2015 13:49:06 +0200
parents a3268580f915
children 072dc455f35e
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java
diffstat 1 files changed, 45 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java	Wed Sep 30 11:38:20 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java	Wed Sep 30 13:49:06 2015 +0200
@@ -22,13 +22,14 @@
  */
 package com.oracle.graal.hotspot;
 
-import static jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime.runtime;
-
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
 import java.io.PrintStream;
 import java.lang.management.ManagementFactory;
 
+import jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime;
 import jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntimeProvider;
 import jdk.internal.jvmci.options.OptionValue;
 
@@ -74,6 +75,47 @@
     }
 
     /**
+     * An output stream that redirects to {@link HotSpotJVMCIRuntimeProvider#getLogStream()}. The
+     * {@link HotSpotJVMCIRuntimeProvider#getLogStream()} value is only accessed the first time an
+     * IO operation is performed on the stream. This is required to break a deadlock in early JVMCI
+     * initialization.
+     */
+    static class DelayedOutputStream extends OutputStream {
+        private volatile OutputStream lazy;
+
+        private OutputStream lazy() {
+            if (lazy == null) {
+                synchronized (this) {
+                    if (lazy == null) {
+                        lazy = HotSpotJVMCIRuntime.runtime().getLogStream();
+                    }
+                }
+            }
+            return lazy;
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+            lazy().write(b, off, len);
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            lazy().write(b);
+        }
+
+        @Override
+        public void flush() throws IOException {
+            lazy().flush();
+        }
+
+        @Override
+        public void close() throws IOException {
+            lazy().close();
+        }
+    }
+
+    /**
      * Gets the print stream configured by this option. If no file is configured, the print stream
      * will output to HotSpot's {@link HotSpotJVMCIRuntimeProvider#getLogStream() log} stream.
      */
@@ -98,7 +140,7 @@
                     }
                 }
             } else {
-                ps = new PrintStream(runtime().getLogStream());
+                ps = new PrintStream(new DelayedOutputStream());
             }
         }
         return ps;