Amp-Thread-ID: https://ampcode.com/threads/T-01a0b382-1e79-712b-abd1-d29201c9bb5e Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
43 lines
1.3 KiB
JavaScript
43 lines
1.3 KiB
JavaScript
// Single-writer/single-reader latest-sample mailbox. Header: state, UTF-8 byte length.
|
|
// State 0 = empty, 1 = owned by a reader/writer, 2 = complete sample.
|
|
// Neither side waits: an unread sample can be replaced, and a busy publication is skipped.
|
|
export class SharedProfile {
|
|
constructor(buffer = new SharedArrayBuffer(1024 * 1024)) {
|
|
this.buffer = buffer;
|
|
this.header = new Int32Array(buffer, 0, 2);
|
|
this.bytes = new Uint8Array(buffer, 8);
|
|
this.encoder = new TextEncoder();
|
|
this.decoder = new TextDecoder();
|
|
}
|
|
|
|
write(json) {
|
|
const bytes = this.encoder.encode(json);
|
|
if (bytes.length > this.bytes.length) return false;
|
|
const state = Atomics.load(this.header, 0);
|
|
if (
|
|
state === 1 ||
|
|
Atomics.compareExchange(this.header, 0, state, 1) !== state
|
|
)
|
|
return false;
|
|
this.bytes.set(bytes);
|
|
this.header[1] = bytes.length;
|
|
Atomics.store(this.header, 0, 2);
|
|
return true;
|
|
}
|
|
|
|
read() {
|
|
if (Atomics.compareExchange(this.header, 0, 2, 1) !== 2) return;
|
|
let bytes;
|
|
try {
|
|
bytes = this.bytes.slice(0, this.header[1]);
|
|
} finally {
|
|
Atomics.store(this.header, 0, 0);
|
|
}
|
|
return JSON.parse(this.decoder.decode(bytes));
|
|
}
|
|
|
|
clear() {
|
|
Atomics.compareExchange(this.header, 0, 2, 0);
|
|
}
|
|
}
|