Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorAlain Magloire2002-09-07 14:46:49 +0000
committerAlain Magloire2002-09-07 14:46:49 +0000
commitf3745131b94ec1b7d4149b9a385d67de2c380559 (patch)
tree1f31dc147280e926f3894f64191d760216cb8355 /core
parent3a354aa2899f5144add507de861bac9cbc96f3d2 (diff)
downloadorg.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.java90
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();
+ }
+ }
+ }
}

Back to the top