src/vs/workbench/contrib/terminal/browser/terminalService.ts/TerminalService/_onBeforeShutdownAsync
class TerminalService:	private async _onBeforeShutdownAsync(reason: ShutdownReason): Promise<boolean> {
		if (this.instances.length === 0) {
			// No terminal instances, don't veto
			return false;
		}

		// Persist terminal _buffer state_, note that even if this happens the dirty terminal prompt
		// still shows as that cannot be revived
		try {
			this._shutdownWindowCount = await this._nativeDelegate?.getWindowCount();
			const shouldReviveProcesses = this._shouldReviveProcesses(reason);
			if (shouldReviveProcesses) {
				// Attempt to persist the terminal state but only allow 2000ms as we can't block
				// shutdown. This can happen when in a remote workspace but the other side has been
				// suspended and is in the process of reconnecting, the message will be put in a
				// queue in this case for when the connection is back up and running. Aborting the
				// process is preferable in this case.
				await Promise.race([
					this._primaryBackend?.persistTerminalState(),
					timeout(2000)
				]);
			}

			// Persist terminal _processes_
			const shouldPersistProcesses = this._configHelper.config.enablePersistentSessions && reason === ShutdownReason.RELOAD;
			if (!shouldPersistProcesses) {
				const hasDirtyInstances = (
					(this.configHelper.config.confirmOnExit === 'always' && this.instances.length > 0) ||
					(this.configHelper.config.confirmOnExit === 'hasChildProcesses' && this.instances.some(e => e.hasChildProcesses))
				);
				if (hasDirtyInstances) {
					return this._onBeforeShutdownConfirmation(reason);
				}
			}
		} catch (err: unknown) {
			// Swallow as exceptions should not cause a veto to prevent shutdown
			this._logService.warn('Exception occurred during terminal shutdown', err);
		}

		this._isShuttingDown = true;

		return false;
	}