Change:
This here: Is strange to me because while this call is , it will not prolong the shutdown on the main process which is sync: Since the user of this event does not seem to use , I suggest to make the not support promises.

Discussion:
// Shared process lifecycle const onExit = async () => { <del> if (this.lifecycleService) { await this.lifecycleService.fireOnWillShutdown(); this.lifecycleService.dispose(); this.lifecycleService = undefined; } </del> <ins> this.lifecycleService?.fireOnWillShutdown(); </ins> this.dispose(); }; process.once('exit', onExit);

private async initServices(): Promise<IInstantiationService> { const services = new ServiceCollection(); <del> // Lifecycle </del> // Product const productService = { _serviceBrand: undefined, ...product }; services.set(IProductService, productService);

services.set(ILogService, logService); // Lifecycle <del> this.lifecycleService = new SharedProcessLifecycleService(logService); </del> <ins> this.lifecycleService = this._register(new SharedProcessLifecycleService(logService)); </ins> services.set(ISharedProcessLifecycleService, this.lifecycleService); // Worker

*  Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ <del> import { Promises } from 'vs/base/common/async'; </del> import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation';

readonly _serviceBrand: undefined; /** <del> * An event that fires after after no window has vetoed the shutdown sequence. At * this point listeners are ensured that the application will quit without veto. </del> <ins> * An event for when the application will shutdown </ins> */ <del> readonly onWillShutdown: Event<ShutdownEvent>; } export interface ShutdownEvent { /** * Allows to join the shutdown. The promise can be a long running operation but it * will block the application from closing. */ join(promise: Promise<void>): void; </del> <ins> readonly onWillShutdown: Event<void>; </ins> } export class SharedProcessLifecycleService extends Disposable implements ISharedProcessLifecycleService { declare readonly _serviceBrand: undefined; <del> private pendingWillShutdownPromise: Promise<void> | undefined = undefined; private readonly _onWillShutdown = this._register(new Emitter<ShutdownEvent>()); </del> <ins> private readonly _onWillShutdown = this._register(new Emitter<void>()); </ins> readonly onWillShutdown = this._onWillShutdown.event; constructor(

super(); } <del> public fireOnWillShutdown(): Promise<void> { if (this.pendingWillShutdownPromise) { return this.pendingWillShutdownPromise; // shutdown is already running } </del> <ins> fireOnWillShutdown(): void { </ins> this.logService.trace('Lifecycle#onWillShutdown.fire()'); <del> const joiners: Promise<void>[] = []; this._onWillShutdown.fire({ join(promise) { joiners.push(promise); } }); this.pendingWillShutdownPromise = (async () => { // Settle all shutdown event joiners try { await Promises.settled(joiners); } catch (error) { this.logService.error(error); } })(); return this.pendingWillShutdownPromise; </del> <ins> this._onWillShutdown.fire(); </ins> } }

this._register(this._logger.onDidChangeLogLevel(l => this._logger.info('Log level changed to ' + LogLevelToString(l)))); <del> this._register(sharedProcessLifecycleService.onWillShutdown(e => { if (this._tunnelProcess) { this._tunnelProcess.cancel(); this._tunnelProcess = undefined; } </del> <ins> this._register(sharedProcessLifecycleService.onWillShutdown(() => { this._tunnelProcess?.cancel(); this._tunnelProcess = undefined; </ins> this.dispose(); }));

} private onWillShutdown(): void { <ins> this.logService.trace('SharedProcess: onWillShutdown'); </ins> const window = this.window; if (!window) { return; // possibly too early before created

// Electron seems to crash on Windows without this setTimeout :| setTimeout(() => { try { <ins> this.logService.trace('SharedProcess: onWillShutdown window.close()'); </ins> window.close(); <del> } catch (err) { // ignore, as electron is already shutting down </del> <ins> } catch (error) { this.logService.trace(`SharedProcess: onWillShutdown window.close() error: ${error}`); // ignore, as electron is already shutting down </ins> } this.window = undefined;