The current implementation of java.lang.Process.destroy() is incorrect. Now it is possible to call destroy and cause some other process to be terminated. Current java.lang.Process implementation is: --- src/solaris/native/java/lang/UNIXProcess_md.c --- JNIEXPORT void JNICALL Java_java_lang_UNIXProcess_destroyProcess(JNIEnv *env, jobject junk, jint pid) { kill(pid, SIGTERM); } --- src/solaris/native/java/lang/UNIXProcess_md.c --- --- src/solaris/classes/java/lang/UNIXProcess.java.linux --- public void destroy() { destroyProcess(pid); try { stdin_stream.close(); stdout_stream.close(); stderr_stream.close(); } catch (IOException e) { // ignore } } --- src/solaris/classes/java/lang/UNIXProcess.java.linux --- As result, the following situation is possible: Thread1 | Thread2 ---------------------------------------------------------------- createProcess | process.pid=X | process.waitFor() | process has been terminated | | | | createProcess | process.pid=X (I know that OS is supposed to avoid assigning same pid for some time but ...) process.destroy() | -> kill(X, SIGTERM) | | got signal and terminated with -1 (according to Java_java_lang_UNIXProcess_waitForProcessExit) | ---------------------------------------------------------------- It would be better if 'destroyProcess(pid)' will be called only in case the process has not been terminated yet. Something like: public void destroy() { synchronized(this) { if (!hasExited) destroyProcess(pid); } try { stdin_stream.close(); stdout_stream.close(); stderr_stream.close(); } catch (IOException e) { // ignore } } I will attach the test case after it will be ready.
|