diff options
author | Alain Magloire | 2002-09-07 14:46:49 +0000 |
---|---|---|
committer | Alain Magloire | 2002-09-07 14:46:49 +0000 |
commit | f3745131b94ec1b7d4149b9a385d67de2c380559 (patch) | |
tree | 1f31dc147280e926f3894f64191d760216cb8355 /core | |
parent | 3a354aa2899f5144add507de861bac9cbc96f3d2 (diff) | |
download | org.eclipse.cdt-f3745131b94ec1b7d4149b9a385d67de2c380559.tar.gz org.eclipse.cdt-f3745131b94ec1b7d4149b9a385d67de2c380559.tar.xz org.eclipse.cdt-f3745131b94ec1b7d4149b9a385d67de2c380559.zip |
LinuxThread seems to behave differently so we change the code
to have one thread doing the code __and__ the wait.
The Spawner reaper thread.
Diffstat (limited to 'core')
-rw-r--r-- | core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java | 90 |
1 files changed, 73 insertions, 17 deletions
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java index 73506ddfa46..36dd0c8cfc1 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java @@ -19,9 +19,10 @@ public class Spawner extends Process { private int KILL = 9; private int TERM = 15; - private int pid = -1; + private int pid = 0; private int status; private int[] channels = new int[3]; + private boolean isDone; OutputStream out; InputStream in; InputStream err; @@ -31,7 +32,7 @@ public class Spawner extends Process { String[] cmdarray = new String[tokenizer.countTokens()]; for (int n = 0; tokenizer.hasMoreTokens(); n++) cmdarray[n] = tokenizer.nextToken(); - if(bNoRedirect) + if (bNoRedirect) exec_detached(cmdarray, new String[0], "."); else exec(cmdarray, new String[0], "."); @@ -97,7 +98,6 @@ public class Spawner extends Process { **/ public InputStream getInputStream() { return in; - //return new SpawnerInputStream(channels[1]); } /** @@ -105,7 +105,6 @@ public class Spawner extends Process { **/ public OutputStream getOutputStream() { return out; - //return new SpawnerOutputStream(channels[0]); } /** @@ -113,14 +112,15 @@ public class Spawner extends Process { **/ public InputStream getErrorStream() { return err; - //return new SpawnerInputStream(channels[2]); } /** * See java.lang.Process#waitFor (); **/ - public int waitFor() throws InterruptedException { - status = waitFor(pid); + public synchronized int waitFor() throws InterruptedException { + while (!isDone) { + wait(); + } try { ((SpawnerInputStream)getErrorStream()).close(); ((SpawnerInputStream)getInputStream()).close(); @@ -133,8 +133,8 @@ public class Spawner extends Process { /** * See java.lang.Process#exitValue (); **/ - public int exitValue() { - if (isRunning()) { + public synchronized int exitValue() { + if (!isDone) { throw new IllegalThreadStateException("Process not Terminated"); } return status; @@ -143,14 +143,25 @@ public class Spawner extends Process { /** * See java.lang.Process#destroy (); **/ - public void destroy() { + public synchronized void destroy() { + // Sends the TERM terminate(); - if (isRunning()) { - kill(); - } + // Close the streams on this side. try { - waitFor(); - } catch (InterruptedException e) { + ((SpawnerInputStream)getErrorStream()).close(); + ((SpawnerInputStream)getInputStream()).close(); + ((SpawnerOutputStream)getOutputStream()).close(); + } catch (IOException e) { + } + // Grace before using the heavy gone. + if (!isDone) { + try { + wait(1000); + } catch (InterruptedException e) { + } + } + if (!isDone) { + kill(); } } @@ -182,10 +193,24 @@ public class Spawner extends Process { SecurityManager s = System.getSecurityManager(); if (s != null) s.checkExec(command); - if (envp == null) envp = new String[0]; - pid = exec0(cmdarray, envp, dirpath, channels); + + Thread reaper = new Reaper(cmdarray, envp, dirpath); + reaper.setDaemon(true); + reaper.start(); + + // Wait until the subprocess is started or error. + synchronized (this) { + while (pid == 0) { + try { + wait(); + } catch (InterruptedException e) { + } + } + } + + // Check for errors. if (pid == -1) { throw new IOException("Exec error"); } @@ -216,4 +241,35 @@ public class Spawner extends Process { static { System.loadLibrary("spawner"); } + + // Spawn a thread to handle the forking and waiting + // We do it this way because on linux the SIGCHLD is + // send to the one thread. So do the forking and + // the wait in the same thread. + class Reaper extends Thread { + String[] cmdarray; + String[] envp; + String dirpath; + public Reaper(String[] array, String[] env, String dir) { + super("Spawner Reaper"); + cmdarray = array; + envp = env; + dirpath = dir; + } + + public void run() { + pid = exec0(cmdarray, envp, dirpath, channels); + // Tell spawner that the process started. + synchronized (Spawner.this) { + Spawner.this.notifyAll(); + } + + // Sync with spawner and notify when done. + status = waitFor(pid); + synchronized (Spawner.this) { + isDone = true; + Spawner.this.notifyAll(); + } + } + } } |