mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-20 16:49:06 +01:00
93 lines
3.4 KiB
JavaScript
93 lines
3.4 KiB
JavaScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
// @ts-check
|
|
const vscode = require('vscode');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const os = require('os');
|
|
|
|
/** @type {string | undefined} */
|
|
let deactivateMarkerFile;
|
|
|
|
/**
|
|
* @param {vscode.ExtensionContext} context
|
|
*/
|
|
function activate(context) {
|
|
// Record extension host pid on every activation so smoke tests can validate
|
|
// that a new extension host process was started after a restart action.
|
|
try {
|
|
const pid = String(process.pid);
|
|
const activationPidFile = path.join(os.tmpdir(), 'vscode-ext-host-pid-on-activate.txt');
|
|
fs.writeFileSync(activationPidFile, pid, 'utf-8');
|
|
} catch {
|
|
// Ignore errors in smoke helper setup.
|
|
}
|
|
|
|
// This is used to verify that the extension host process is properly killed
|
|
// when window reloads even if the extension host is blocked
|
|
// Refs: https://github.com/microsoft/vscode/issues/291346
|
|
context.subscriptions.push(
|
|
vscode.commands.registerCommand('smoketest.getExtensionHostPidAndBlock', (delayMs = 100, durationMs = 60000) => {
|
|
const pid = process.pid;
|
|
|
|
// Write PID file to temp dir to avoid polluting workspace search results
|
|
// Note: filename must match name in extension-host-restart.test.ts
|
|
const pidFile = path.join(os.tmpdir(), 'vscode-ext-host-pid.txt');
|
|
setTimeout(() => {
|
|
fs.writeFileSync(pidFile, String(pid), 'utf-8');
|
|
|
|
// Block the extension host without busy-spinning to avoid pegging a CPU core.
|
|
// Prefer Atomics.wait on a SharedArrayBuffer when available; otherwise, fall back
|
|
// to the original busy loop to preserve behavior in older environments.
|
|
if (typeof SharedArrayBuffer === 'function' && typeof Atomics !== 'undefined' && typeof Atomics.wait === 'function') {
|
|
const sab = new SharedArrayBuffer(4);
|
|
const blocker = new Int32Array(sab);
|
|
// Wait up to durationMs milliseconds. This blocks the thread without consuming CPU.
|
|
Atomics.wait(blocker, 0, 0, durationMs);
|
|
} else {
|
|
const start = Date.now();
|
|
while (Date.now() - start < durationMs) {
|
|
// Busy loop (fallback)
|
|
}
|
|
}
|
|
}, delayMs);
|
|
|
|
return pid;
|
|
})
|
|
);
|
|
|
|
// This command sets up a marker file path that will be written during deactivation.
|
|
// It allows the smoke test to verify that extensions get a chance to deactivate.
|
|
context.subscriptions.push(
|
|
vscode.commands.registerCommand('smoketest.setupGracefulDeactivation', () => {
|
|
const pid = process.pid;
|
|
const pidFile = path.join(os.tmpdir(), 'vscode-ext-host-pid-graceful.txt');
|
|
deactivateMarkerFile = path.join(os.tmpdir(), 'vscode-ext-host-deactivated.txt');
|
|
|
|
// Write PID file immediately so test knows the extension is ready
|
|
fs.writeFileSync(pidFile, String(pid), 'utf-8');
|
|
|
|
return { pid, markerFile: deactivateMarkerFile };
|
|
})
|
|
);
|
|
}
|
|
|
|
function deactivate() {
|
|
// Write marker file to indicate deactivation was called
|
|
if (deactivateMarkerFile) {
|
|
try {
|
|
fs.writeFileSync(deactivateMarkerFile, `deactivated at ${Date.now()}`, 'utf-8');
|
|
} catch {
|
|
// Ignore errors (e.g., folder not accessible)
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
activate,
|
|
deactivate
|
|
};
|