Skip to content

Commit 3fbd2fc

Browse files
datho7561fbricon
authored andcommitted
Use ProcessHandle instead of shell script to check for parent process
See #1025 Signed-off-by: David Thompson <davthomp@redhat.com>
1 parent 3ee1cfd commit 3fbd2fc

File tree

1 file changed

+3
-56
lines changed

1 file changed

+3
-56
lines changed

org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/commons/ParentProcessWatcher.java

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,14 @@
1212
*******************************************************************************/
1313
package org.eclipse.lemminx.commons;
1414

15-
import static org.eclipse.lemminx.utils.platform.Platform.isWindows;
16-
17-
import java.io.IOException;
15+
import java.util.Optional;
1816
import java.util.concurrent.Executors;
1917
import java.util.concurrent.ScheduledExecutorService;
2018
import java.util.concurrent.ScheduledFuture;
2119
import java.util.concurrent.TimeUnit;
2220
import java.util.function.Function;
23-
import java.util.logging.Level;
2421
import java.util.logging.Logger;
2522

26-
import com.google.common.io.Closeables;
27-
2823
import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
2924
import org.eclipse.lsp4j.services.LanguageServer;
3025

@@ -36,7 +31,6 @@
3631
public final class ParentProcessWatcher implements Runnable, Function<MessageConsumer, MessageConsumer> {
3732

3833
private static final Logger LOGGER = Logger.getLogger(ParentProcessWatcher.class.getName());
39-
private static final boolean isJava1x = System.getProperty("java.version").startsWith("1.");
4034

4135
/**
4236
* Exit code returned when XML Language Server is forced to exit.
@@ -84,55 +78,8 @@ private boolean parentProcessStillRunning() {
8478
if (pid == 0 || lastActivityTime > (System.currentTimeMillis() - INACTIVITY_DELAY_SECS)) {
8579
return true;
8680
}
87-
String command;
88-
if (isWindows) {
89-
command = "cmd /c \"tasklist /FI \"PID eq " + pid + "\" | findstr " + pid + "\"";
90-
} else {
91-
command = "kill -0 " + pid;
92-
}
93-
Process process = null;
94-
boolean finished = false;
95-
try {
96-
process = Runtime.getRuntime().exec(command);
97-
finished = process.waitFor(POLL_DELAY_SECS, TimeUnit.SECONDS);
98-
if (!finished) {
99-
process.destroy();
100-
finished = process.waitFor(POLL_DELAY_SECS, TimeUnit.SECONDS); // wait for the process to stop
101-
}
102-
if (isWindows && finished && process.exitValue() > 1) {
103-
// the tasklist command should return 0 (parent process exists) or 1 (parent process doesn't exist)
104-
LOGGER.warning("The tasklist command: '" + command + "' returns " + process.exitValue());
105-
return true;
106-
}
107-
return !finished || process.exitValue() == 0;
108-
} catch (IOException | InterruptedException e) {
109-
LOGGER.log(Level.WARNING, e.getMessage(), e);
110-
return true;
111-
} finally {
112-
if (process != null) {
113-
if (!finished) {
114-
process.destroyForcibly();
115-
}
116-
// Terminating or destroying the Process doesn't close the process handle on Windows.
117-
// It is only closed when the Process object is garbage collected (in its finalize() method).
118-
// On Windows, when the Java LS is idle, we need to explicitly request a GC,
119-
// to prevent an accumulation of zombie processes, as finalize() will be called.
120-
if (isWindows) {
121-
// Java >= 9 doesn't close the handle when the process is garbage collected
122-
// We need to close the opened streams
123-
if (!isJava1x) {
124-
Closeables.closeQuietly(process.getInputStream());
125-
Closeables.closeQuietly(process.getErrorStream());
126-
try {
127-
Closeables.close(process.getOutputStream(), false);
128-
} catch (IOException e) {
129-
}
130-
}
131-
System.gc();
132-
}
133-
}
134-
}
135-
81+
Optional<ProcessHandle> optionalHandle = ProcessHandle.of(pid);
82+
return !optionalHandle.isEmpty() && optionalHandle.get().isAlive();
13683
}
13784

13885
@Override

0 commit comments

Comments
 (0)