diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2019-03-14 19:17:52 -0400 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-03-15 10:58:18 -0400 |
commit | 1811318097b57c136913bd95bb9e16d820cc1a1a (patch) | |
tree | 1459444a37d4ea961d1b1f1da2cd0044ed2c5ac9 /core/shared_queue.js | |
parent | 76c73ec61ec4271581795a2f0e3ae60072676dae (diff) |
core: Behavior shouldn't be generic
We always pass around Box<[u8]>, and adding this generic is an
unnecessary complication.
Add deno_core_http_bench_test to test.py
sharedQueue works on deno_core_http_bench
Diffstat (limited to 'core/shared_queue.js')
-rw-r--r-- | core/shared_queue.js | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/core/shared_queue.js b/core/shared_queue.js new file mode 100644 index 000000000..36f5dc91b --- /dev/null +++ b/core/shared_queue.js @@ -0,0 +1,127 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +(window => { + const MAX_RECORDS = 100; + const INDEX_NUM_RECORDS = 0; + const INDEX_NUM_SHIFTED_OFF = 1; + const INDEX_HEAD = 2; + const INDEX_OFFSETS = 3; + const INDEX_RECORDS = 3 + MAX_RECORDS; + const HEAD_INIT = 4 * INDEX_RECORDS; + + let sharedBytes = null; + let shared32 = null; + + if (!window["Deno"]) { + window["Deno"] = {}; + } + + function assert(cond) { + if (!cond) { + throw Error("assert"); + } + } + + function reset() { + shared32.fill(0, 0, INDEX_RECORDS); + shared32[INDEX_HEAD] = HEAD_INIT; + } + + function head() { + return shared32[INDEX_HEAD]; + } + + function numRecords() { + return shared32[INDEX_NUM_RECORDS]; + } + + function setEnd(index, end) { + shared32[INDEX_OFFSETS + index] = end; + } + + function getEnd(index) { + if (index < numRecords()) { + return shared32[INDEX_OFFSETS + index]; + } else { + return null; + } + } + + function getOffset(index) { + if (index < numRecords()) { + if (index == 0) { + return HEAD_INIT; + } else { + return shared32[INDEX_OFFSETS + index - 1]; + } + } else { + return null; + } + } + + function push(buf) { + let off = head(); + let end = off + buf.byteLength; + let index = numRecords(); + if (end > shared32.byteLength) { + console.log("shared_queue.ts push fail"); + return false; + } + setEnd(index, end); + assert(end - off == buf.byteLength); + sharedBytes.set(buf, off); + shared32[INDEX_NUM_RECORDS] += 1; + shared32[INDEX_HEAD] = end; + return true; + } + + /// Returns null if empty. + function shift() { + let i = shared32[INDEX_NUM_SHIFTED_OFF]; + if (i >= numRecords()) { + return null; + } + let off = getOffset(i); + let end = getEnd(i); + shared32[INDEX_NUM_SHIFTED_OFF] += 1; + return sharedBytes.subarray(off, end); + } + + function size() { + return shared32[INDEX_NUM_RECORDS] - shared32[INDEX_NUM_SHIFTED_OFF]; + } + + let asyncHandler = null; + function setAsyncHandler(cb) { + assert(asyncHandler == null); + asyncHandler = cb; + } + + function handleAsyncMsgFromRust() { + let buf; + while ((buf = shift()) != null) { + asyncHandler(buf); + } + } + + function init(shared) { + assert(shared.byteLength > 0); + assert(sharedBytes == null); + assert(shared32 == null); + sharedBytes = new Uint8Array(shared); + shared32 = new Int32Array(shared); + // Callers should not call libdeno.recv, use setAsyncHandler. + libdeno.recv(handleAsyncMsgFromRust); + } + + window.Deno._setAsyncHandler = setAsyncHandler; + window.Deno._sharedQueue = { + head, + numRecords, + size, + push, + reset, + shift + }; + + init(libdeno.shared); +})(this); |