提交 8a6b8fd5 编写于 作者: S Sandeep Somavarapu

Clean up thred service

上级 cf6b4b56
......@@ -132,7 +132,13 @@ class ExtensionHostProcessManager {
PIPE_LOGGING: 'true',
VERBOSE_LOGGING: true,
VSCODE_WINDOW_ID: String(this.windowService.getWindowId())
})
}),
// We only detach the extension host on windows. Linux and Mac orphan by default
// and detach under Linux and Mac create another process group.
// We detach because we have noticed that when the renderer exits, its child processes
// (i.e. extension host) is taken down in a brutal fashion by the OS
detached: !!isWindows,
onExtensionHostMessage
};
// Help in case we fail to start it
......@@ -145,20 +151,16 @@ class ExtensionHostProcessManager {
}
// Initialize extension host process with hand shakes
this.initializeExtensionHostProcess = new TPromise<ChildProcess>((c, e) => {
this.initializeExtensionHostProcess = this.doInitializeExtensionHostProcess(opts);
}
private doInitializeExtensionHostProcess(opts: any): TPromise<ChildProcess> {
return new TPromise<ChildProcess>((c, e) => {
// Resolve additional execution args (e.g. debug)
return this.resolveDebugPort(this.environmentService.debugExtensionHost.port, port => {
this.resolveDebugPort(this.environmentService.debugExtensionHost.port).then(port => {
if (port) {
opts.execArgv = ['--nolazy', (this.isExtensionDevelopmentDebugging ? '--debug-brk=' : '--debug=') + port];
}
// We only detach the extension host on windows. Linux and Mac orphan by default
// and detach under Linux and Mac create another process group.
if (isWindows) {
// We detach because we have noticed that when the renderer exits, its child processes
// (i.e. extension host) is taken down in a brutal fashion by the OS
opts.detached = true;
}
// Run Extension Host as fork of current process
this.extensionHostProcessHandle = fork(URI.parse(require.toUrl('bootstrap')).fsPath, ['--type=extensionHost'], opts);
......@@ -172,10 +174,72 @@ class ExtensionHostProcessManager {
}
// Messages from Extension host
this.extensionHostProcessHandle.on('message', (msg) => {
this.extensionHostProcessHandle.on('message', msg => {
if (this.onMessaage(msg, opts.onExtensionHostMessage)) {
c(this.extensionHostProcessHandle);
}
});
// Lifecycle
let onExit = () => this.terminate();
process.once('exit', onExit);
this.extensionHostProcessHandle.on('error', (err) => this.onError(err));
this.extensionHostProcessHandle.on('exit', (code: any, signal: any) => this.onExit(code, signal, onExit));
});
}, () => this.terminate());
}
private resolveDebugPort(extensionHostPort: number): TPromise<number> {
if (typeof extensionHostPort !== 'number') {
return TPromise.wrap(void 0);
}
return new TPromise<number>((c, e) => {
findFreePort(extensionHostPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */, (port) => {
if (!port) {
console.warn('%c[Extension Host] %cCould not find a free port for debugging', 'color: blue', 'color: black');
c(void 0);
}
if (port !== extensionHostPort) {
console.warn('%c[Extension Host] %cProvided debugging port ' + extensionHostPort + ' is not free, using ' + port + ' instead.', 'color: blue', 'color: black');
}
if (this.isExtensionDevelopmentDebugging) {
console.warn('%c[Extension Host] %cSTOPPED on first line for debugging on port ' + port, 'color: blue', 'color: black');
} else {
console.info('%c[Extension Host] %cdebugger listening on port ' + port, 'color: blue', 'color: black');
}
return c(port);
});
});
}
// @return `true` if ready
private onMessaage(msg : any, onExtensionHostMessage : (msg: any) => void): boolean {
// 1) Host is ready to receive messages, initialize it
if (msg === 'ready') {
this.initializeExtensionHost();
return false;
}
// 2) Host is initialized
if (msg === 'initialized') {
this.unsentMessages.forEach(m => this.postMessage(m));
this.unsentMessages = [];
this.extensionHostProcessReady = true;
return true;
}
// Support logging from extension host
if (msg && (<ILogEntry>msg).type === '__$console') {
this.logExtensionHostMessage(<ILogEntry>msg);
return false;
}
// Any other message goes to the callback
onExtensionHostMessage(msg);
return false;
}
private initializeExtensionHost() {
if (this.initializeTimer) {
window.clearTimeout(this.initializeTimer);
}
......@@ -197,19 +261,7 @@ class ExtensionHostProcessManager {
this.extensionHostProcessHandle.send(initPayload);
}
// 2) Host is initialized
else if (msg === 'initialized') {
this.unsentMessages.forEach(m => this.postMessage(m));
this.unsentMessages = [];
this.extensionHostProcessReady = true;
c(this.extensionHostProcessHandle);
}
// Support logging from extension host
else if (msg && (<ILogEntry>msg).type === '__$console') {
let logEntry: ILogEntry = msg;
private logExtensionHostMessage(logEntry: ILogEntry) {
let args = [];
try {
let parsed = JSON.parse(logEntry.arguments);
......@@ -247,17 +299,7 @@ class ExtensionHostProcessManager {
}
}
// Any other message goes to the callback
else {
onExtensionHostMessage(msg);
}
});
// Lifecycle
let onExit = () => this.terminate();
process.once('exit', onExit);
this.extensionHostProcessHandle.on('error', (err) => {
private onError(err: any): void {
let errorMessage = toErrorMessage(err);
if (errorMessage === this.lastExtensionHostError) {
return; // prevent error spam
......@@ -266,10 +308,10 @@ class ExtensionHostProcessManager {
this.lastExtensionHostError = errorMessage;
this.messageService.show(Severity.Error, nls.localize('extensionHostProcess.error', "Error from the extension host: {0}", errorMessage));
});
}
this.extensionHostProcessHandle.on('exit', (code: any, signal: any) => {
process.removeListener('exit', onExit);
private onExit(code: any, signal: any, onProcessExit: any): void {
process.removeListener('exit', onProcessExit);
if (!this.terminating) {
......@@ -292,40 +334,6 @@ class ExtensionHostProcessManager {
ipc.send('vscode:exit', code);
}
}
});
});
}, () => this.terminate());
}
private resolveDebugPort(extensionHostPort: number, clb: (port: number) => void): void {
// Check for a free debugging port
if (typeof extensionHostPort === 'number') {
return findFreePort(extensionHostPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */, (port) => {
if (!port) {
console.warn('%c[Extension Host] %cCould not find a free port for debugging', 'color: blue', 'color: black');
return clb(void 0);
}
if (port !== extensionHostPort) {
console.warn('%c[Extension Host] %cProvided debugging port ' + extensionHostPort + ' is not free, using ' + port + ' instead.', 'color: blue', 'color: black');
}
if (this.isExtensionDevelopmentDebugging) {
console.warn('%c[Extension Host] %cSTOPPED on first line for debugging on port ' + port, 'color: blue', 'color: black');
} else {
console.info('%c[Extension Host] %cdebugger listening on port ' + port, 'color: blue', 'color: black');
}
return clb(port);
});
}
// Nothing to do here
else {
return clb(void 0);
}
}
public postMessage(msg: any): void {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册