Skip to content

Commit 140b1ef

Browse files
Ensure children of OmniSharp server process are killed on Unix
1 parent bc23294 commit 140b1ef

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

src/common.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import * as cp from 'child_process';
77
import * as fs from 'fs';
8+
import * as os from 'os';
89
import * as path from 'path';
910

1011
let extensionPath: string;
@@ -60,6 +61,41 @@ export function execChildProcess(command: string, workingDirectory: string = get
6061
});
6162
}
6263

64+
export function getUnixChildProcessIds(pid: number): Promise<number[]> {
65+
return new Promise<number[]>((resolve, reject) => {
66+
let ps = cp.exec('ps -A -o ppid,pid', (error, stdout, stderr) =>
67+
{
68+
if (error) {
69+
return reject(error);
70+
}
71+
72+
if (stderr) {
73+
return reject(stderr);
74+
}
75+
76+
if (!stdout) {
77+
return resolve([]);
78+
}
79+
80+
let lines = stdout.split(os.EOL);
81+
let pairs = lines.map(line => line.trim().split(/\s+/));
82+
83+
let children = [];
84+
85+
for (let pair of pairs) {
86+
let ppid = parseInt(pair[0]);
87+
if (ppid === pid) {
88+
children.push(parseInt(pair[1]));
89+
}
90+
}
91+
92+
resolve(children);
93+
});
94+
95+
ps.on('error', reject);
96+
});
97+
}
98+
6399
export function fileExists(filePath: string): Promise<boolean> {
64100
return new Promise<boolean>((resolve, reject) => {
65101
fs.stat(filePath, (err, stats) => {

src/omnisharp/server.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import TelemetryReporter from 'vscode-extension-telemetry';
1616
import * as os from 'os';
1717
import * as path from 'path';
1818
import * as protocol from './protocol';
19+
import * as utils from '../common';
1920
import * as vscode from 'vscode';
2021

2122
enum ServerState {
@@ -337,9 +338,15 @@ export class OmniSharpServer {
337338
});
338339
}
339340
else {
340-
// Kill Unix process
341-
this._serverProcess.kill('SIGTERM');
342-
cleanupPromise = Promise.resolve();
341+
// Kill Unix process and children
342+
cleanupPromise = utils.getUnixChildProcessIds(this._serverProcess.pid)
343+
.then(children => {
344+
for (let child of children) {
345+
process.kill(child, 'SIGTERM');
346+
}
347+
348+
this._serverProcess.kill('SIGTERM');
349+
});
343350
}
344351

345352
return cleanupPromise.then(() => {

0 commit comments

Comments
 (0)