< prev index next >

src/java.base/share/classes/java/lang/ProcessBuilder.java

Print this page
imported patch ProcessEnvironment-race

*** 23,32 **** --- 23,34 ---- * questions. */ package java.lang; + import java.lang.invoke.MethodHandles; + import java.lang.invoke.VarHandle; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;
*** 207,217 **** * @param command the list containing the program and its arguments */ public ProcessBuilder(List<String> command) { if (command == null) throw new NullPointerException(); ! this.command = command; } /** * Constructs a process builder with the specified operating * system program and arguments. This is a convenience --- 209,219 ---- * @param command the list containing the program and its arguments */ public ProcessBuilder(List<String> command) { if (command == null) throw new NullPointerException(); ! COMMAND.setRelease(this, command); } /** * Constructs a process builder with the specified operating * system program and arguments. This is a convenience
*** 222,234 **** * command. * * @param command a string array containing the program and its arguments */ public ProcessBuilder(String... command) { ! this.command = new ArrayList<>(command.length); for (String arg : command) ! this.command.add(arg); } /** * Sets this process builder's operating system program and * arguments. This method does <i>not</i> make a copy of the --- 224,237 ---- * command. * * @param command a string array containing the program and its arguments */ public ProcessBuilder(String... command) { ! List<String> commandList = new ArrayList<>(command.length); for (String arg : command) ! commandList.add(arg); ! COMMAND.setRelease(this, commandList); } /** * Sets this process builder's operating system program and * arguments. This method does <i>not</i> make a copy of the
*** 241,251 **** * @return this process builder */ public ProcessBuilder command(List<String> command) { if (command == null) throw new NullPointerException(); ! this.command = command; return this; } /** * Sets this process builder's operating system program and --- 244,254 ---- * @return this process builder */ public ProcessBuilder command(List<String> command) { if (command == null) throw new NullPointerException(); ! COMMAND.setRelease(this, command); return this; } /** * Sets this process builder's operating system program and
*** 272,282 **** * process builder. * * @return this process builder's program and its arguments */ public List<String> command() { ! return command; } /** * Returns a string map view of this process builder's environment. * --- 275,285 ---- * process builder. * * @return this process builder's program and its arguments */ public List<String> command() { ! return (List<String>) COMMAND.getAcquire(this); } /** * Returns a string map view of this process builder's environment. *
*** 348,363 **** public Map<String,String> environment() { SecurityManager security = System.getSecurityManager(); if (security != null) security.checkPermission(new RuntimePermission("getenv.*")); ! if (environment == null) ! environment = ProcessEnvironment.environment(); ! ! assert environment != null; ! return environment; } // Only for use by Runtime.exec(...envp...) ProcessBuilder environment(String[] envp) { assert environment == null; --- 351,369 ---- public Map<String,String> environment() { SecurityManager security = System.getSecurityManager(); if (security != null) security.checkPermission(new RuntimePermission("getenv.*")); ! // Multiple threads may call this method without synchronization ! for (;;) { ! Map<String,String> environment = (Map<String,String>) ! ENVIRONMENT.getAcquire(this); ! if (environment != null) return environment; + ENVIRONMENT.compareAndSet(this, null, + ProcessEnvironment.environment()); + } } // Only for use by Runtime.exec(...envp...) ProcessBuilder environment(String[] envp) { assert environment == null;
*** 1296,1301 **** --- 1302,1322 ---- }); throw ex; } return processes; } + + // VarHandle mechanics + private static final VarHandle COMMAND; + private static final VarHandle ENVIRONMENT; + static { + try { + MethodHandles.Lookup l = MethodHandles.lookup(); + COMMAND = l.findVarHandle( + ProcessBuilder.class, "command", List.class); + ENVIRONMENT = l.findVarHandle( + ProcessBuilder.class, "environment", Map.class); + } catch (ReflectiveOperationException e) { + throw new ExceptionInInitializerError(e); + } + } }
< prev index next >