mirror of
https://github.com/nodejs/node.git
synced 2025-05-16 07:33:15 +00:00

PR-URL: https://github.com/nodejs/node/pull/54077 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
111 lines
4.5 KiB
JavaScript
111 lines
4.5 KiB
JavaScript
|
|
// Copyright 2024 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
//
|
|
// Flags: --harmony-struct --allow-natives-syntax
|
|
if (this.Worker) {
|
|
(function TestWorkerTerminated() {
|
|
let workerLockScript = `onmessage = function({data:msg}) {
|
|
let {mutex, sharedObj} = msg;
|
|
Atomics.Mutex.lock(mutex, function() {
|
|
postMessage('Lock acquired');
|
|
while(!Atomics.load(sharedObj, 'done')) {}
|
|
});
|
|
postMessage('Lock released');
|
|
};
|
|
postMessage('Worker started');`;
|
|
let workerWaitScript = `onmessage = function({data:msg}) {
|
|
let {cv_mutex, cv, shared_Obj} = msg;
|
|
Atomics.Mutex.lock(cv_mutex, function() {
|
|
postMessage('Waiting started');
|
|
Atomics.Condition.wait(cv, cv_mutex);
|
|
});
|
|
postMessage('Waiting done');
|
|
};
|
|
postMessage('Worker started');`;
|
|
let workerAsyncScript = `onmessage = function({data:msg}) {
|
|
if (msg.type === 'lock') {
|
|
let {mutex, sharedObj} = msg;
|
|
for (let i = 0; i < 10; i++) {
|
|
Atomics.Mutex.lockAsync(mutex, async function() {})
|
|
}
|
|
postMessage('Lock waiters queued');
|
|
}
|
|
else if (msg.type === 'wait'){
|
|
let {cv_mutex, cv} = msg;
|
|
for (let i = 0; i < 10; i++) {
|
|
Atomics.Mutex.lockAsync(cv_mutex, async function() {
|
|
await Atomics.Condition.waitAsync(cv, cv_mutex);
|
|
})
|
|
}
|
|
// The waiters will be processed when the microtask queue is flushed
|
|
// after this task. This will queue both tasks and microtasks, so other
|
|
// incoming tasks might be handled before the the waitAsyncs are
|
|
// executed.
|
|
postMessage('Handled wait messages');
|
|
}
|
|
else {
|
|
postMessage(%AtomicsSychronizationNumAsyncWaitersInIsolateForTesting());
|
|
}
|
|
};
|
|
postMessage('Worker started');`;
|
|
|
|
let workerLock1 = new Worker(workerLockScript, {type: 'string'});
|
|
assertEquals('Worker started', workerLock1.getMessage());
|
|
let workerLock2 = new Worker(workerLockScript, {type: 'string'});
|
|
assertEquals('Worker started', workerLock2.getMessage());
|
|
let workerWait1 = new Worker(workerWaitScript, {type: 'string'});
|
|
assertEquals('Worker started', workerWait1.getMessage());
|
|
let workerWait2 = new Worker(workerWaitScript, {type: 'string'});
|
|
assertEquals('Worker started', workerWait2.getMessage());
|
|
let workerAsync = new Worker(workerAsyncScript, {type: 'string'});
|
|
assertEquals('Worker started', workerAsync.getMessage());
|
|
let SharedType = new SharedStructType(['done']);
|
|
let sharedObj = new SharedType();
|
|
sharedObj.done = false;
|
|
let mutex = new Atomics.Mutex;
|
|
let cv_mutex = new Atomics.Mutex;
|
|
let cv = new Atomics.Condition;
|
|
let lock_msg = {mutex, sharedObj, type: 'lock'};
|
|
let wait_msg = {cv_mutex, cv, type: 'wait'};
|
|
let count_msg = {type: 'count'};
|
|
workerLock1.postMessage(lock_msg);
|
|
workerWait1.postMessage(wait_msg);
|
|
assertEquals('Lock acquired', workerLock1.getMessage());
|
|
assertEquals('Waiting started', workerWait1.getMessage());
|
|
workerAsync.postMessage(lock_msg);
|
|
assertEquals('Lock waiters queued', workerAsync.getMessage());
|
|
workerAsync.postMessage(wait_msg);
|
|
assertEquals('Handled wait messages', workerAsync.getMessage());
|
|
// Wait until the waitAsync-related tasks are processed in the worker before
|
|
// posting a new message.
|
|
while(%AtomicsSynchronizationPrimitiveNumWaitersForTesting(cv) !== 11) {
|
|
}
|
|
// Verify there are 30 waiters in the async waiter list of the workerAsync's
|
|
// isolate.
|
|
workerAsync.postMessage(count_msg);
|
|
assertEquals(30, workerAsync.getMessage());
|
|
workerLock2.postMessage(lock_msg);
|
|
workerWait2.postMessage(wait_msg);
|
|
assertEquals('Waiting started', workerWait2.getMessage());
|
|
while(%AtomicsSynchronizationPrimitiveNumWaitersForTesting(cv) !== 12) {
|
|
}
|
|
workerAsync.terminate();
|
|
while(!Atomics.Mutex.tryLock(cv_mutex, function() {
|
|
sharedObj.done = true;
|
|
Atomics.Condition.notify(cv, 20);
|
|
}).success) {
|
|
}
|
|
assertEquals('Lock released', workerLock1.getMessage());
|
|
assertEquals('Lock acquired', workerLock2.getMessage());
|
|
assertEquals('Lock released', workerLock2.getMessage());
|
|
assertEquals('Waiting done', workerWait1.getMessage());
|
|
assertEquals('Waiting done', workerWait2.getMessage());
|
|
workerLock1.terminate();
|
|
workerLock2.terminate();
|
|
workerWait1.terminate();
|
|
workerWait2.terminate();
|
|
})();
|
|
}
|