Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/test/smoke/extensions/vscode-smoketest-ext-host/extension.js
5334 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
// @ts-check
7
const vscode = require('vscode');
8
const fs = require('fs');
9
const path = require('path');
10
const os = require('os');
11
12
/** @type {string | undefined} */
13
let deactivateMarkerFile;
14
15
/**
16
* @param {vscode.ExtensionContext} context
17
*/
18
function activate(context) {
19
// This is used to verify that the extension host process is properly killed
20
// when window reloads even if the extension host is blocked
21
// Refs: https://github.com/microsoft/vscode/issues/291346
22
context.subscriptions.push(
23
vscode.commands.registerCommand('smoketest.getExtensionHostPidAndBlock', (delayMs = 100, durationMs = 60000) => {
24
const pid = process.pid;
25
26
// Write PID file to workspace folder if available, otherwise temp dir
27
// Note: filename must match name in extension-host-restart.test.ts
28
const workspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
29
const pidFile = workspaceFolder
30
? path.join(workspaceFolder, 'vscode-ext-host-pid.txt')
31
: path.join(os.tmpdir(), 'vscode-ext-host-pid.txt');
32
setTimeout(() => {
33
fs.writeFileSync(pidFile, String(pid), 'utf-8');
34
35
// Block the extension host without busy-spinning to avoid pegging a CPU core.
36
// Prefer Atomics.wait on a SharedArrayBuffer when available; otherwise, fall back
37
// to the original busy loop to preserve behavior in older environments.
38
if (typeof SharedArrayBuffer === 'function' && typeof Atomics !== 'undefined' && typeof Atomics.wait === 'function') {
39
const sab = new SharedArrayBuffer(4);
40
const blocker = new Int32Array(sab);
41
// Wait up to durationMs milliseconds. This blocks the thread without consuming CPU.
42
Atomics.wait(blocker, 0, 0, durationMs);
43
} else {
44
const start = Date.now();
45
while (Date.now() - start < durationMs) {
46
// Busy loop (fallback)
47
}
48
}
49
}, delayMs);
50
51
return pid;
52
})
53
);
54
55
// This command sets up a marker file path that will be written during deactivation.
56
// It allows the smoke test to verify that extensions get a chance to deactivate.
57
context.subscriptions.push(
58
vscode.commands.registerCommand('smoketest.setupGracefulDeactivation', () => {
59
const pid = process.pid;
60
const workspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
61
const pidFile = workspaceFolder
62
? path.join(workspaceFolder, 'vscode-ext-host-pid-graceful.txt')
63
: path.join(os.tmpdir(), 'vscode-ext-host-pid-graceful.txt');
64
deactivateMarkerFile = workspaceFolder
65
? path.join(workspaceFolder, 'vscode-ext-host-deactivated.txt')
66
: path.join(os.tmpdir(), 'vscode-ext-host-deactivated.txt');
67
68
// Write PID file immediately so test knows the extension is ready
69
fs.writeFileSync(pidFile, String(pid), 'utf-8');
70
71
return { pid, markerFile: deactivateMarkerFile };
72
})
73
);
74
}
75
76
function deactivate() {
77
// Write marker file to indicate deactivation was called
78
if (deactivateMarkerFile) {
79
try {
80
fs.writeFileSync(deactivateMarkerFile, `deactivated at ${Date.now()}`, 'utf-8');
81
} catch {
82
// Ignore errors (e.g., folder not accessible)
83
}
84
}
85
}
86
87
module.exports = {
88
activate,
89
deactivate
90
};
91
92