src/vs/workbench/api/node/extensionHostProcess.ts/connectToRenderer
function connectToRenderer(protocol: IMessagePassingProtocol): Promise<IRendererConnection> {
	return new Promise<IRendererConnection>((c) => {

		// Listen init data message
		const first = protocol.onMessage(raw => {
			first.dispose();

			const initData = <IExtensionHostInitData>JSON.parse(raw.toString());

			const rendererCommit = initData.commit;
			const myCommit = product.commit;

			if (rendererCommit && myCommit) {
				// Running in the built version where commits are defined
				if (rendererCommit !== myCommit) {
					nativeExit(ExtensionHostExitCode.VersionMismatch);
				}
			}

			if (initData.parentPid) {
				// Kill oneself if one's parent dies. Much drama.
				let epermErrors = 0;
				setInterval(function () {
					try {
						process.kill(initData.parentPid, 0); // throws an exception if the main process doesn't exist anymore.
						epermErrors = 0;
					} catch (e) {
						if (e && e.code === 'EPERM') {
							// Even if the parent process is still alive,
							// some antivirus software can lead to an EPERM error to be thrown here.
							// Let's terminate only if we get 3 consecutive EPERM errors.
							epermErrors++;
							if (epermErrors >= 3) {
								onTerminate(`parent process ${initData.parentPid} does not exist anymore (3 x EPERM): ${e.message} (code: ${e.code}) (errno: ${e.errno})`);
							}
						} else {
							onTerminate(`parent process ${initData.parentPid} does not exist anymore: ${e.message} (code: ${e.code}) (errno: ${e.errno})`);
						}
					}
				}, 1000);

				// In certain cases, the event loop can become busy and never yield
				// e.g. while-true or process.nextTick endless loops
				// So also use the native node module to do it from a separate thread
				let watchdog: typeof nativeWatchdog;
				try {
					watchdog = globalThis._VSCODE_NODE_MODULES['native-watchdog'];
					watchdog.start(initData.parentPid);
				} catch (err) {
					// no problem...
					onUnexpectedError(err);
				}
			}

			// Tell the outside that we are initialized
			protocol.send(createMessageOfType(MessageType.Initialized));

			c({ protocol, initData });
		});

		// Tell the outside that we are ready to receive messages
		protocol.send(createMessageOfType(MessageType.Ready));
	});
}