node/deps/v8/test/mjsunit/shared-memory/async-synchronization-workers-terminated.js
Michaël Zasso 9d7cd9b864
deps: update V8 to 12.8.374.13
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>
2024-08-16 16:03:01 +02:00

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();
})();
}