atomics-sync
Version:
JavaScript multithreading synchronization library
49 lines (41 loc) • 1.72 kB
text/typescript
const { compareExchange, store } = Atomics;
/**
* A synchronization primitive that ensures a function is executed only once,
* even when called from multiple threads.
* Uses atomic operations for thread-safe execution tracking.
*/
export class Once {
// Index for the execution state in the shared array
private static readonly INDEX_EXECUTED = 0;
// Possible execution states
private static readonly EXECUTED_NO = 0; // Function has not been executed
private static readonly EXECUTED_YES = 1; // Function has been executed
/**
* Initializes a new Once primitive in shared memory
* @returns A new Int32Array backed by SharedArrayBuffer initialized to NOT_EXECUTED
*/
static init() {
const once = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
store(once, Once.INDEX_EXECUTED, Once.EXECUTED_NO);
return once;
}
/**
* Executes the provided function exactly once, even if called from multiple threads
* @param once The Once primitive to use for synchronization
* @param fn The function to execute (will be called at most once)
* @remarks The function will be called by whichever thread wins the atomic race
*/
static execute(once: Int32Array<SharedArrayBuffer>, fn: () => void) {
if (compareExchange(once, Once.INDEX_EXECUTED, Once.EXECUTED_NO, Once.EXECUTED_YES) === Once.EXECUTED_NO) {
fn();
}
}
/**
* Checks if the function has been executed
* @param once The Once primitive to check
* @returns true if the function has been executed, false otherwise
*/
static isExecuted(once: Int32Array<SharedArrayBuffer>): boolean {
return Atomics.load(once, Once.INDEX_EXECUTED) === Once.EXECUTED_YES;
}
}