123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.SyncMessenger = void 0;
- /**
- * @param condition Condition to wait for, when true, the function returns.
- * @param ms Maximum time to wait in milliseconds.
- */
- const sleepUntil = (condition, ms = 100) => {
- const start = Date.now();
- while (!condition()) {
- const now = Date.now();
- if (now - start > ms)
- throw new Error('Timeout');
- }
- };
- /**
- * `SyncMessenger` allows to execute asynchronous code synchronously. The
- * asynchronous code is executed in a Worker thread, while the main thread is
- * blocked until the asynchronous code is finished.
- *
- * First four 4-byte words is the header, where the first word is used for Atomics
- * notifications. The second word is used for spin-locking the main thread until
- * the asynchronous code is finished. The third word is used to specify payload
- * length. The fourth word is currently unused.
- *
- * The maximum payload size is the size of the SharedArrayBuffer minus the
- * header size.
- */
- class SyncMessenger {
- constructor(sab) {
- this.sab = sab;
- this.int32 = new Int32Array(sab);
- this.uint8 = new Uint8Array(sab);
- this.headerSize = 4 * 4;
- this.dataSize = sab.byteLength - this.headerSize;
- }
- callSync(data) {
- const requestLength = data.length;
- const headerSize = this.headerSize;
- const int32 = this.int32;
- int32[1] = 0;
- int32[2] = requestLength;
- this.uint8.set(data, headerSize);
- Atomics.notify(int32, 0);
- sleepUntil(() => int32[1] === 1);
- const responseLength = int32[2];
- const response = this.uint8.slice(headerSize, headerSize + responseLength);
- return response;
- }
- serveAsync(callback) {
- const headerSize = this.headerSize;
- (async () => {
- try {
- const int32 = this.int32;
- const res = Atomics.wait(int32, 0, 0);
- if (res !== 'ok')
- throw new Error(`Unexpected Atomics.wait result: ${res}`);
- const requestLength = this.int32[2];
- const request = this.uint8.slice(headerSize, headerSize + requestLength);
- const response = await callback(request);
- const responseLength = response.length;
- int32[2] = responseLength;
- this.uint8.set(response, headerSize);
- int32[1] = 1;
- }
- catch (_a) { }
- this.serveAsync(callback);
- })().catch(() => { });
- }
- }
- exports.SyncMessenger = SyncMessenger;
- //# sourceMappingURL=SyncMessenger.js.map
|