knitting 0.1.51 → 0.1.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +213 -54
- package/knitting.d.ts +1 -0
- package/map.md +15 -3
- package/package.json +14 -2
- package/prebuilds/darwin-arm64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/darwin-arm64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/darwin-x64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/darwin-x64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/linux-x64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/linux-x64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/win32-x64/knitting_windows_shared_memory.dll +0 -0
- package/prebuilds/win32-x64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/win32-x64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/win32-x64-node-127/knitting_shm.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_shm.node +0 -0
- package/scripts/build-native-addons.ts +5 -0
- package/src/api.d.ts +29 -16
- package/src/api.js +98 -28
- package/src/common/envelope.d.ts +9 -3
- package/src/common/envelope.js +14 -0
- package/src/common/worker-runtime.d.ts +2 -0
- package/src/common/worker-runtime.js +9 -0
- package/src/connections/buffer-reference-native.d.ts +56 -0
- package/src/connections/buffer-reference-native.js +217 -0
- package/src/connections/buffer-reference.d.ts +78 -0
- package/src/connections/buffer-reference.js +461 -0
- package/src/connections/index.d.ts +1 -0
- package/src/connections/index.js +1 -0
- package/src/connections/node-addons.d.ts +1 -1
- package/src/connections/node-buffer-pointer.d.ts +20 -0
- package/src/connections/node-buffer-pointer.js +16 -0
- package/src/connections/process-shared-buffer.d.ts +6 -0
- package/src/connections/process-shared-buffer.js +6 -0
- package/src/connections/shared-array-buffer-payload.d.ts +36 -0
- package/src/connections/shared-array-buffer-payload.js +235 -0
- package/src/debug/env-diff.d.ts +26 -0
- package/src/debug/env-diff.js +49 -0
- package/src/debug/gate.d.ts +18 -0
- package/src/debug/gate.js +69 -0
- package/src/debug/handle.d.ts +23 -0
- package/src/debug/handle.js +48 -0
- package/src/ipc/transport/shared-memory.d.ts +1 -3
- package/src/knitting_buffer_pointer.cc +425 -0
- package/src/memory/lock.d.ts +12 -1
- package/src/memory/lock.js +47 -4
- package/src/memory/payload-config.d.ts +9 -0
- package/src/memory/payloadCodec.js +220 -37
- package/src/permission/protocol.d.ts +1 -1
- package/src/permission/protocol.js +30 -20
- package/src/runtime/pool.d.ts +3 -5
- package/src/runtime/pool.js +18 -18
- package/src/runtime/process-worker.js +5 -2
- package/src/runtime/tx-queue.d.ts +3 -2
- package/src/runtime/tx-queue.js +18 -13
- package/src/types.d.ts +54 -50
- package/src/utils/http.d.ts +29 -0
- package/src/utils/http.js +100 -0
- package/src/worker/loop.js +76 -14
- package/src/worker/rx-queue.d.ts +4 -1
- package/src/worker/rx-queue.js +53 -4
- package/src/worker/safety/startup.d.ts +2 -3
- package/src/worker/safety/startup.js +1 -4
- package/src/worker/timers.js +7 -2
- package/unsafe.d.ts +1 -0
- package/unsafe.js +1 -0
- package/utils.d.ts +1 -0
- package/utils.js +1 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { beginPromisePayload, finishPromisePayload, getTaskSlotIndex, HEADER_BYTE_LENGTH, HEADER_SLOT_STRIDE_U32, HEADER_STATIC_PAYLOAD_U32, LockBound, PayloadBuffer, PayloadSignal, TaskIndex, } from "./lock.js";
|
|
1
|
+
import { attachPayloadTransportFinalizer, beginPromisePayload, finishPromisePayload, getTaskSlotIndex, HEADER_BYTE_LENGTH, HEADER_SLOT_STRIDE_U32, HEADER_STATIC_PAYLOAD_U32, LockBound, PayloadBuffer, PayloadSignal, TaskIndex, } from "./lock.js";
|
|
2
2
|
import { register } from "./regionRegistry.js";
|
|
3
3
|
import { createSharedDynamicBufferIO, createSharedStaticBufferIO, } from "./shared-buffer-io.js";
|
|
4
4
|
import { getStridedRegionSpanBytes } from "./byte-carpet.js";
|
|
5
5
|
import { encoderError, ErrorKnitting } from "../error.js";
|
|
6
6
|
import { Envelope } from "../common/envelope.js";
|
|
7
7
|
import { resolvePayloadBufferOptions, } from "./payload-config.js";
|
|
8
|
+
import { getSharedArrayBufferPayload, SHARED_ARRAY_BUFFER_CODEC_ID, SHARED_ARRAY_BUFFER_NUMERIC_TRANSFER, SHARED_ARRAY_BUFFER_NUMERIC_WORDS, } from "../connections/shared-array-buffer-payload.js";
|
|
9
|
+
const BUFFER_REFERENCE_NUMERIC_TRANSFER = Symbol.for("knitting.bufferReference.numericTransfer");
|
|
8
10
|
const memory = new ArrayBuffer(8);
|
|
9
11
|
const Float64View = new Float64Array(memory);
|
|
10
12
|
const BigInt64View = new BigInt64Array(memory);
|
|
@@ -28,6 +30,7 @@ const BIGINT64_MAX = (1n << 63n) - 1n;
|
|
|
28
30
|
const { parse: parseJSON, stringify: stringifyJSON } = JSON;
|
|
29
31
|
const { for: symbolFor, keyFor: symbolKeyFor } = Symbol;
|
|
30
32
|
const EXTERNAL_PAYLOAD_BRAND = symbolFor("knitting.payloadCodec");
|
|
33
|
+
const BUFFER_REFERENCE_CODEC_ID = "knitting.bufferReference";
|
|
31
34
|
const PROCESS_SHARED_BUFFER_CODEC_ID = "knitting.processSharedBuffer";
|
|
32
35
|
const externalPayloadGlobal = globalThis;
|
|
33
36
|
const objectGetPrototypeOf = Object.getPrototypeOf;
|
|
@@ -35,7 +38,8 @@ const objectHasOwn = Object.prototype.hasOwnProperty;
|
|
|
35
38
|
const arrayIsArray = Array.isArray;
|
|
36
39
|
const objectPrototype = Object.prototype;
|
|
37
40
|
const UNSUPPORTED_OBJECT_DETAIL = "Unsupported object type. Allowed: plain object, array, Error, Date, Envelope, Buffer, ArrayBuffer, DataView, typed arrays, and registered external payloads. Serialize it yourself.";
|
|
38
|
-
const ENVELOPE_PAYLOAD_DETAIL = "Envelope payload must be an ArrayBuffer
|
|
41
|
+
const ENVELOPE_PAYLOAD_DETAIL = "Envelope payload must be an ArrayBuffer, SharedArrayBuffer, " +
|
|
42
|
+
"ProcessSharedBuffer, or BufferReference.";
|
|
39
43
|
const ENVELOPE_HEADER_DETAIL = "Envelope header must be a JSON-like value or string.";
|
|
40
44
|
const ENVELOPE_PROMISE_DETAIL = "Envelope header cannot contain Promise values.";
|
|
41
45
|
const DYNAMIC_PAYLOAD_LIMIT_DETAIL = "Dynamic payload exceeds maxPayloadBytes.";
|
|
@@ -92,15 +96,18 @@ const decodeExternalPayload = (raw) => {
|
|
|
92
96
|
: { codec: codecId, metadata };
|
|
93
97
|
};
|
|
94
98
|
const PROCESS_SHARED_BUFFER_NUMERIC_WORDS = 8;
|
|
99
|
+
const BUFFER_REFERENCE_NUMERIC_WORDS = 8;
|
|
95
100
|
const NUMERIC_SENTINEL = 0xffffffff;
|
|
96
|
-
const
|
|
97
|
-
const codec = externalPayloadGlobal.__KNITTING_PAYLOAD_CODECS__?.[
|
|
98
|
-
if (typeof codec?.decodeNumeric === "function")
|
|
101
|
+
const decodeNumericExternalPayload = (codecId, words) => {
|
|
102
|
+
const codec = externalPayloadGlobal.__KNITTING_PAYLOAD_CODECS__?.[codecId];
|
|
103
|
+
if (typeof codec?.decodeNumeric === "function") {
|
|
99
104
|
return codec.decodeNumeric(words);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return { codec: PROCESS_SHARED_BUFFER_CODEC_ID, metadata: Array.from(words) };
|
|
105
|
+
}
|
|
106
|
+
return { codec: codecId, metadata: Array.from(words) };
|
|
103
107
|
};
|
|
108
|
+
const decodeProcessSharedBufferNumericWords = (words) => decodeNumericExternalPayload(PROCESS_SHARED_BUFFER_CODEC_ID, words);
|
|
109
|
+
const decodeBufferReferenceNumericWords = (words) => decodeNumericExternalPayload(BUFFER_REFERENCE_CODEC_ID, words);
|
|
110
|
+
const decodeSharedArrayBufferNumericWords = (words) => decodeNumericExternalPayload(SHARED_ARRAY_BUFFER_CODEC_ID, words);
|
|
104
111
|
const tryEncodePrimitiveTask = (task) => {
|
|
105
112
|
const value = task.value;
|
|
106
113
|
switch (typeof value) {
|
|
@@ -516,6 +523,7 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
516
523
|
return true;
|
|
517
524
|
};
|
|
518
525
|
const processSharedBufferWords = new Uint32Array(PROCESS_SHARED_BUFFER_NUMERIC_WORDS);
|
|
526
|
+
const sharedArrayBufferWords = new Uint32Array(SHARED_ARRAY_BUFFER_NUMERIC_WORDS);
|
|
519
527
|
const tryEncodeProcessSharedBufferNumeric = (task, slotIndex, value) => {
|
|
520
528
|
const descriptor = value.descriptor;
|
|
521
529
|
if (descriptor === undefined ||
|
|
@@ -549,6 +557,33 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
549
557
|
task.value = null;
|
|
550
558
|
return true;
|
|
551
559
|
};
|
|
560
|
+
const tryEncodeBufferReferenceNumeric = (task, slotIndex, value) => {
|
|
561
|
+
const words = value[BUFFER_REFERENCE_NUMERIC_TRANSFER]?.();
|
|
562
|
+
if (words === undefined)
|
|
563
|
+
return false;
|
|
564
|
+
task[TaskIndex.Type] = PayloadBuffer.BufferReference;
|
|
565
|
+
task[TaskIndex.PayloadLen] = writeStaticU32Words(words, BUFFER_REFERENCE_NUMERIC_WORDS, slotIndex);
|
|
566
|
+
attachPayloadTransportFinalizer(task, value);
|
|
567
|
+
task.value = null;
|
|
568
|
+
return true;
|
|
569
|
+
};
|
|
570
|
+
const tryEncodeSharedArrayBufferNumeric = (task, slotIndex, value) => {
|
|
571
|
+
const words = value[SHARED_ARRAY_BUFFER_NUMERIC_TRANSFER]?.(lockSector);
|
|
572
|
+
if (words === undefined)
|
|
573
|
+
return false;
|
|
574
|
+
sharedArrayBufferWords[0] = words[0] ?? 0;
|
|
575
|
+
sharedArrayBufferWords[1] = words[1] ?? 0;
|
|
576
|
+
sharedArrayBufferWords[2] = words[2] ?? 0;
|
|
577
|
+
sharedArrayBufferWords[3] = words[3] ?? 0;
|
|
578
|
+
sharedArrayBufferWords[4] = words[4] ?? 0;
|
|
579
|
+
sharedArrayBufferWords[5] = words[5] ?? 0;
|
|
580
|
+
sharedArrayBufferWords[6] = words[6] ?? 0;
|
|
581
|
+
sharedArrayBufferWords[7] = words[7] ?? 0;
|
|
582
|
+
task[TaskIndex.Type] = PayloadBuffer.SharedArrayBuffer;
|
|
583
|
+
task[TaskIndex.PayloadLen] = writeStaticU32Words(sharedArrayBufferWords, words.length, slotIndex);
|
|
584
|
+
task.value = null;
|
|
585
|
+
return true;
|
|
586
|
+
};
|
|
552
587
|
const encodeObjectExternalPayload = (task, slotIndex, externalPayload) => {
|
|
553
588
|
const codecId = readExternalPayloadCodecId(externalPayload);
|
|
554
589
|
if (codecId === undefined) {
|
|
@@ -559,6 +594,14 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
559
594
|
detail: UNSUPPORTED_OBJECT_DETAIL,
|
|
560
595
|
});
|
|
561
596
|
}
|
|
597
|
+
if (codecId === SHARED_ARRAY_BUFFER_CODEC_ID &&
|
|
598
|
+
tryEncodeSharedArrayBufferNumeric(task, slotIndex, externalPayload)) {
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
if (codecId === BUFFER_REFERENCE_CODEC_ID &&
|
|
602
|
+
tryEncodeBufferReferenceNumeric(task, slotIndex, externalPayload)) {
|
|
603
|
+
return true;
|
|
604
|
+
}
|
|
562
605
|
if (codecId === PROCESS_SHARED_BUFFER_CODEC_ID &&
|
|
563
606
|
tryEncodeProcessSharedBufferNumeric(task, slotIndex, externalPayload)) {
|
|
564
607
|
return true;
|
|
@@ -589,6 +632,7 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
589
632
|
if (written !== -1) {
|
|
590
633
|
task[TaskIndex.Type] = PayloadBuffer.StaticExternalPayload;
|
|
591
634
|
task[TaskIndex.PayloadLen] = written;
|
|
635
|
+
attachPayloadTransportFinalizer(task, externalPayload);
|
|
592
636
|
task.value = null;
|
|
593
637
|
return true;
|
|
594
638
|
}
|
|
@@ -603,6 +647,7 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
603
647
|
return failDynamicWriteAfterReserve(task, reservedSlot);
|
|
604
648
|
task[TaskIndex.PayloadLen] = written;
|
|
605
649
|
setSlotLength(reservedSlot, written);
|
|
650
|
+
attachPayloadTransportFinalizer(task, externalPayload);
|
|
606
651
|
task.value = null;
|
|
607
652
|
return true;
|
|
608
653
|
};
|
|
@@ -614,52 +659,50 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
614
659
|
task.value = null;
|
|
615
660
|
return true;
|
|
616
661
|
};
|
|
617
|
-
const
|
|
618
|
-
const header = envelope.header;
|
|
619
|
-
const payload = envelope.payload;
|
|
620
|
-
const headerIsString = typeof header === "string";
|
|
621
|
-
if (!(payload instanceof ArrayBuffer)) {
|
|
622
|
-
return encoderError({
|
|
623
|
-
task,
|
|
624
|
-
type: ErrorKnitting.Serializable,
|
|
625
|
-
onPromise,
|
|
626
|
-
detail: ENVELOPE_PAYLOAD_DETAIL,
|
|
627
|
-
});
|
|
628
|
-
}
|
|
662
|
+
const encodeEnvelopeHeaderText = (task, header, headerIsString) => {
|
|
629
663
|
if (hasPromiseInEnvelopeHeader(header)) {
|
|
630
|
-
|
|
664
|
+
encoderError({
|
|
631
665
|
task,
|
|
632
666
|
type: ErrorKnitting.Serializable,
|
|
633
667
|
onPromise,
|
|
634
668
|
detail: ENVELOPE_PROMISE_DETAIL,
|
|
635
669
|
});
|
|
670
|
+
return undefined;
|
|
636
671
|
}
|
|
672
|
+
if (headerIsString)
|
|
673
|
+
return header;
|
|
637
674
|
let headerText;
|
|
638
|
-
|
|
639
|
-
headerText = header;
|
|
675
|
+
try {
|
|
676
|
+
headerText = stringifyJSON(header);
|
|
640
677
|
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
catch (error) {
|
|
646
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
647
|
-
return encoderError({
|
|
648
|
-
task,
|
|
649
|
-
type: ErrorKnitting.Json,
|
|
650
|
-
onPromise,
|
|
651
|
-
detail,
|
|
652
|
-
});
|
|
653
|
-
}
|
|
678
|
+
catch (error) {
|
|
679
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
680
|
+
encoderError({ task, type: ErrorKnitting.Json, onPromise, detail });
|
|
681
|
+
return undefined;
|
|
654
682
|
}
|
|
655
683
|
if (typeof headerText !== "string") {
|
|
656
|
-
|
|
684
|
+
encoderError({
|
|
657
685
|
task,
|
|
658
686
|
type: ErrorKnitting.Serializable,
|
|
659
687
|
onPromise,
|
|
660
688
|
detail: ENVELOPE_HEADER_DETAIL,
|
|
661
689
|
});
|
|
690
|
+
return undefined;
|
|
691
|
+
}
|
|
692
|
+
return headerText;
|
|
693
|
+
};
|
|
694
|
+
const resolveEnvelopeExternalBody = (body) => {
|
|
695
|
+
if (body === null || typeof body !== "object")
|
|
696
|
+
return undefined;
|
|
697
|
+
const sharedArrayBuffer = getSharedArrayBufferPayload(body);
|
|
698
|
+
if (sharedArrayBuffer !== undefined)
|
|
699
|
+
return sharedArrayBuffer;
|
|
700
|
+
if (isExternalPayloadLike(body)) {
|
|
701
|
+
return body;
|
|
662
702
|
}
|
|
703
|
+
return undefined;
|
|
704
|
+
};
|
|
705
|
+
const encodeEnvelopeArrayBufferBody = (task, slotIndex, headerText, headerIsString, payload) => {
|
|
663
706
|
const payloadBytes = new Uint8Array(payload);
|
|
664
707
|
const payloadLength = payloadBytes.byteLength;
|
|
665
708
|
const payloadReserveBytes = payloadLength > 0 ? payloadLength : 1;
|
|
@@ -707,6 +750,107 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
707
750
|
task.value = null;
|
|
708
751
|
return true;
|
|
709
752
|
};
|
|
753
|
+
const encodeEnvelopeExternalBody = (task, slotIndex, headerText, headerIsString, externalBody) => {
|
|
754
|
+
const codecId = readExternalPayloadCodecId(externalBody);
|
|
755
|
+
if (codecId === undefined) {
|
|
756
|
+
return encoderError({
|
|
757
|
+
task,
|
|
758
|
+
type: ErrorKnitting.Serializable,
|
|
759
|
+
onPromise,
|
|
760
|
+
detail: ENVELOPE_PAYLOAD_DETAIL,
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
let bodyText;
|
|
764
|
+
try {
|
|
765
|
+
bodyText = stringifyJSON([codecId, externalBody.toMetadata()]);
|
|
766
|
+
}
|
|
767
|
+
catch (error) {
|
|
768
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
769
|
+
return encoderError({
|
|
770
|
+
task,
|
|
771
|
+
type: ErrorKnitting.Serializable,
|
|
772
|
+
onPromise,
|
|
773
|
+
detail,
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
if (typeof bodyText !== "string") {
|
|
777
|
+
return encoderError({
|
|
778
|
+
task,
|
|
779
|
+
type: ErrorKnitting.Serializable,
|
|
780
|
+
onPromise,
|
|
781
|
+
detail: "Envelope body metadata must be JSON serializable.",
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
const bodyBytes = textEncode.encode(bodyText);
|
|
785
|
+
const bodyLength = bodyBytes.byteLength;
|
|
786
|
+
const staticHeaderWritten = writeStaticUtf8(headerText, slotIndex);
|
|
787
|
+
if (staticHeaderWritten !== -1) {
|
|
788
|
+
if (!ensureWithinDynamicLimit(task, bodyLength, "EnvelopeStaticHeaderExternal"))
|
|
789
|
+
return false;
|
|
790
|
+
const reservedSlot = reserveDynamicObject(task, bodyLength);
|
|
791
|
+
task[TaskIndex.Type] = headerIsString
|
|
792
|
+
? PayloadBuffer.EnvelopeStaticHeaderStringExternal
|
|
793
|
+
: PayloadBuffer.EnvelopeStaticHeaderExternal;
|
|
794
|
+
task[TaskIndex.PayloadLen] = staticHeaderWritten;
|
|
795
|
+
task[TaskIndex.End] = bodyLength;
|
|
796
|
+
const bodyWritten = writeDynamicBinary(bodyBytes, task[TaskIndex.Start]);
|
|
797
|
+
if (bodyWritten < 0) {
|
|
798
|
+
return failDynamicWriteAfterReserve(task, reservedSlot);
|
|
799
|
+
}
|
|
800
|
+
setSlotLength(reservedSlot, bodyWritten);
|
|
801
|
+
attachPayloadTransportFinalizer(task, externalBody);
|
|
802
|
+
task.value = null;
|
|
803
|
+
return true;
|
|
804
|
+
}
|
|
805
|
+
const headerReserveBytes = dynamicUtf8ReserveBytesWithExtra(task, headerText, bodyLength, headerIsString
|
|
806
|
+
? "EnvelopeDynamicHeaderStringExternal"
|
|
807
|
+
: "EnvelopeDynamicHeaderExternal");
|
|
808
|
+
if (headerReserveBytes < 0)
|
|
809
|
+
return false;
|
|
810
|
+
task[TaskIndex.Type] = headerIsString
|
|
811
|
+
? PayloadBuffer.EnvelopeDynamicHeaderStringExternal
|
|
812
|
+
: PayloadBuffer.EnvelopeDynamicHeaderExternal;
|
|
813
|
+
const reservedSlot = reserveDynamicObject(task, headerReserveBytes + bodyLength);
|
|
814
|
+
const baseStart = task[TaskIndex.Start];
|
|
815
|
+
const writtenHeaderBytes = writeDynamicUtf8(headerText, baseStart, headerReserveBytes);
|
|
816
|
+
if (writtenHeaderBytes < 0) {
|
|
817
|
+
return failDynamicWriteAfterReserve(task, reservedSlot);
|
|
818
|
+
}
|
|
819
|
+
const bodyWritten = writeDynamicBinary(bodyBytes, baseStart + writtenHeaderBytes);
|
|
820
|
+
if (bodyWritten < 0) {
|
|
821
|
+
return failDynamicWriteAfterReserve(task, reservedSlot);
|
|
822
|
+
}
|
|
823
|
+
task[TaskIndex.PayloadLen] = writtenHeaderBytes;
|
|
824
|
+
task[TaskIndex.End] = bodyLength;
|
|
825
|
+
setSlotLength(reservedSlot, writtenHeaderBytes + bodyLength);
|
|
826
|
+
attachPayloadTransportFinalizer(task, externalBody);
|
|
827
|
+
task.value = null;
|
|
828
|
+
return true;
|
|
829
|
+
};
|
|
830
|
+
const encodeObjectEnvelope = (task, slotIndex, envelope) => {
|
|
831
|
+
const header = envelope.header;
|
|
832
|
+
const payload = envelope.payload;
|
|
833
|
+
const headerIsString = typeof header === "string";
|
|
834
|
+
if (payload instanceof ArrayBuffer) {
|
|
835
|
+
const headerText = encodeEnvelopeHeaderText(task, header, headerIsString);
|
|
836
|
+
if (headerText === undefined)
|
|
837
|
+
return false;
|
|
838
|
+
return encodeEnvelopeArrayBufferBody(task, slotIndex, headerText, headerIsString, payload);
|
|
839
|
+
}
|
|
840
|
+
const externalBody = resolveEnvelopeExternalBody(payload);
|
|
841
|
+
if (externalBody !== undefined) {
|
|
842
|
+
const headerText = encodeEnvelopeHeaderText(task, header, headerIsString);
|
|
843
|
+
if (headerText === undefined)
|
|
844
|
+
return false;
|
|
845
|
+
return encodeEnvelopeExternalBody(task, slotIndex, headerText, headerIsString, externalBody);
|
|
846
|
+
}
|
|
847
|
+
return encoderError({
|
|
848
|
+
task,
|
|
849
|
+
type: ErrorKnitting.Serializable,
|
|
850
|
+
onPromise,
|
|
851
|
+
detail: ENVELOPE_PAYLOAD_DETAIL,
|
|
852
|
+
});
|
|
853
|
+
};
|
|
710
854
|
const encodeObjectPromise = (task, promise) => {
|
|
711
855
|
if (beginPromisePayload(task)) {
|
|
712
856
|
promise.then((value) => {
|
|
@@ -769,6 +913,10 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
769
913
|
objectDynamicSlot = -1;
|
|
770
914
|
try {
|
|
771
915
|
const objectValue = args;
|
|
916
|
+
const sharedArrayBufferPayload = getSharedArrayBufferPayload(objectValue);
|
|
917
|
+
if (sharedArrayBufferPayload !== undefined) {
|
|
918
|
+
return encodeObjectExternalPayload(task, slotIndex, sharedArrayBufferPayload);
|
|
919
|
+
}
|
|
772
920
|
const objectProto = objectGetPrototypeOf(objectValue);
|
|
773
921
|
if (isRuntimeUint8Array(objectValue)) {
|
|
774
922
|
return encodeObjectUint8Array(task, slotIndex, objectValue);
|
|
@@ -963,6 +1111,8 @@ export const decodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
963
1111
|
// decode is single-consumer and not re-entrant, and the words are consumed
|
|
964
1112
|
// synchronously when building the ProcessSharedBuffer.
|
|
965
1113
|
const processSharedBufferWords = new Uint32Array(PROCESS_SHARED_BUFFER_NUMERIC_WORDS);
|
|
1114
|
+
const sharedArrayBufferWords = new Uint32Array(SHARED_ARRAY_BUFFER_NUMERIC_WORDS);
|
|
1115
|
+
const bufferReferenceWords = new Uint32Array(BUFFER_REFERENCE_NUMERIC_WORDS);
|
|
966
1116
|
// TODO: remove slotIndex and make that all their callers
|
|
967
1117
|
// store the slot in their Task, to just get it when it comes
|
|
968
1118
|
// to the static versions of decoding
|
|
@@ -1037,6 +1187,33 @@ export const decodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
1037
1187
|
freeTaskSlot(task);
|
|
1038
1188
|
return;
|
|
1039
1189
|
}
|
|
1190
|
+
case PayloadBuffer.EnvelopeStaticHeaderExternal:
|
|
1191
|
+
case PayloadBuffer.EnvelopeStaticHeaderStringExternal: {
|
|
1192
|
+
const rawHeader = readStaticUtf8(0, task[TaskIndex.PayloadLen], slotIndex);
|
|
1193
|
+
const header = task[TaskIndex.Type] ===
|
|
1194
|
+
PayloadBuffer.EnvelopeStaticHeaderStringExternal
|
|
1195
|
+
? rawHeader
|
|
1196
|
+
: parseJSON(rawHeader);
|
|
1197
|
+
const bodyStart = task[TaskIndex.Start];
|
|
1198
|
+
const body = decodeExternalPayload(readDynamicUtf8(bodyStart, bodyStart + task[TaskIndex.End]));
|
|
1199
|
+
task.value = new Envelope(header, body);
|
|
1200
|
+
freeTaskSlot(task);
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
case PayloadBuffer.EnvelopeDynamicHeaderExternal:
|
|
1204
|
+
case PayloadBuffer.EnvelopeDynamicHeaderStringExternal: {
|
|
1205
|
+
const headerStart = task[TaskIndex.Start];
|
|
1206
|
+
const bodyStart = headerStart + task[TaskIndex.PayloadLen];
|
|
1207
|
+
const rawHeader = readDynamicUtf8(headerStart, bodyStart);
|
|
1208
|
+
const header = task[TaskIndex.Type] ===
|
|
1209
|
+
PayloadBuffer.EnvelopeDynamicHeaderStringExternal
|
|
1210
|
+
? rawHeader
|
|
1211
|
+
: parseJSON(rawHeader);
|
|
1212
|
+
const body = decodeExternalPayload(readDynamicUtf8(bodyStart, bodyStart + task[TaskIndex.End]));
|
|
1213
|
+
task.value = new Envelope(header, body);
|
|
1214
|
+
freeTaskSlot(task);
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1040
1217
|
case PayloadBuffer.BigInt:
|
|
1041
1218
|
task.value = decodeBigIntBinary(readDynamicBufferCopy(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]));
|
|
1042
1219
|
freeTaskSlot(task);
|
|
@@ -1113,6 +1290,12 @@ export const decodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
1113
1290
|
case PayloadBuffer.ProcessSharedBuffer:
|
|
1114
1291
|
task.value = decodeProcessSharedBufferNumericWords(readStaticU32Words(processSharedBufferWords, PROCESS_SHARED_BUFFER_NUMERIC_WORDS, slotIndex));
|
|
1115
1292
|
return;
|
|
1293
|
+
case PayloadBuffer.SharedArrayBuffer:
|
|
1294
|
+
task.value = decodeSharedArrayBufferNumericWords(readStaticU32Words(sharedArrayBufferWords, task[TaskIndex.PayloadLen] >>> 2, slotIndex));
|
|
1295
|
+
return;
|
|
1296
|
+
case PayloadBuffer.BufferReference:
|
|
1297
|
+
task.value = decodeBufferReferenceNumericWords(readStaticU32Words(bufferReferenceWords, BUFFER_REFERENCE_NUMERIC_WORDS, slotIndex));
|
|
1298
|
+
return;
|
|
1116
1299
|
case PayloadBuffer.Date:
|
|
1117
1300
|
Uint32View[0] = task[TaskIndex.Start];
|
|
1118
1301
|
Uint32View[1] = task[TaskIndex.End];
|
|
@@ -163,4 +163,4 @@ export declare const resolvePermissionProtocol: ({ permission, modules, }: {
|
|
|
163
163
|
modules?: string[];
|
|
164
164
|
}) => ResolvedPermissionProtocol | undefined;
|
|
165
165
|
export declare const toRuntimePermissionFlags: (protocol: ResolvedPermissionProtocol | undefined) => string[];
|
|
166
|
-
export type {
|
|
166
|
+
export type { DenoPermissionSettings, NodePermissionSettings, PermissionEnvironment, PermissionLegacyMode, PermissionMode, PermissionPath, PermissionProtocol, PermissionProtocolInput, ResolvedPermissionProtocol, SysApiName, };
|
|
@@ -107,11 +107,14 @@ const normalizeSysApiList = (values) => {
|
|
|
107
107
|
return out;
|
|
108
108
|
};
|
|
109
109
|
const hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
110
|
-
const normalizeProtocolInput = (input) => !input
|
|
110
|
+
const normalizeProtocolInput = (input) => !input
|
|
111
|
+
? undefined
|
|
112
|
+
: (typeof input === "string" ? { mode: input } : input);
|
|
111
113
|
const isWindows = () => {
|
|
112
114
|
const nodeProcess = getNodeProcess();
|
|
113
|
-
if (typeof nodeProcess?.platform === "string")
|
|
115
|
+
if (typeof nodeProcess?.platform === "string") {
|
|
114
116
|
return nodeProcess.platform === "win32";
|
|
117
|
+
}
|
|
115
118
|
const g = globalThis;
|
|
116
119
|
return g.Deno?.build?.os === "windows";
|
|
117
120
|
};
|
|
@@ -146,7 +149,8 @@ const getHome = () => {
|
|
|
146
149
|
}
|
|
147
150
|
const g = globalThis;
|
|
148
151
|
try {
|
|
149
|
-
const home = g.Deno?.env?.get?.("HOME") ??
|
|
152
|
+
const home = g.Deno?.env?.get?.("HOME") ??
|
|
153
|
+
g.Deno?.env?.get?.("USERPROFILE");
|
|
150
154
|
if (typeof home === "string" && home.length > 0)
|
|
151
155
|
return home;
|
|
152
156
|
}
|
|
@@ -198,7 +202,11 @@ const toPathList = (values, cwd, home) => {
|
|
|
198
202
|
};
|
|
199
203
|
const toUniquePathList = (values, cwd, home) => normalizeList(toPathList(values, cwd, home));
|
|
200
204
|
const toEnvFiles = (input, cwd, home) => {
|
|
201
|
-
const values = Array.isArray(input)
|
|
205
|
+
const values = Array.isArray(input)
|
|
206
|
+
? input
|
|
207
|
+
: input
|
|
208
|
+
? [input]
|
|
209
|
+
: [DEFAULT_ENV_FILE];
|
|
202
210
|
return toUniquePathList(values, cwd, home);
|
|
203
211
|
};
|
|
204
212
|
const rawRealpathSync = realpathSyncCompat.native ?? realpathSyncCompat;
|
|
@@ -212,7 +220,8 @@ const isPathWithin = (base, candidate) => {
|
|
|
212
220
|
const canonicalBase = toCanonicalPath(base);
|
|
213
221
|
const canonicalCandidate = toCanonicalPath(candidate);
|
|
214
222
|
const relative = pathRelative(canonicalBase, canonicalCandidate);
|
|
215
|
-
return relative === "" ||
|
|
223
|
+
return relative === "" ||
|
|
224
|
+
(!relative.startsWith("..") && !pathIsAbsolute(relative));
|
|
216
225
|
};
|
|
217
226
|
const defaultSensitiveProjectAndHomePaths = (cwd, home) => {
|
|
218
227
|
const projectSensitive = DEFAULT_DENY_RELATIVE.map((entry) => pathResolve(cwd, entry));
|
|
@@ -343,6 +352,13 @@ const toDenoFlags = ({ read, readAll, write, writeAll, denyRead, denyWrite, net,
|
|
|
343
352
|
flags.push(`--deny-env=${envDeny.join(",")}`);
|
|
344
353
|
}
|
|
345
354
|
for (const file of envFiles) {
|
|
355
|
+
try {
|
|
356
|
+
if (!existsSyncCompat(file))
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
346
362
|
flags.push(`--env-file=${file}`);
|
|
347
363
|
}
|
|
348
364
|
if (runAll) {
|
|
@@ -476,9 +492,7 @@ export const resolvePermissionProtocol = ({ permission, modules, }) => {
|
|
|
476
492
|
const configuredRead = readAll
|
|
477
493
|
? []
|
|
478
494
|
: toPathList(Array.isArray(input.read) ? input.read : undefined, cwd, home);
|
|
479
|
-
const configuredWrite = writeAll
|
|
480
|
-
? []
|
|
481
|
-
: toPathList(Array.isArray(input.write) ? input.write : undefined, cwd, home);
|
|
495
|
+
const configuredWrite = writeAll ? [] : toPathList(Array.isArray(input.write) ? input.write : undefined, cwd, home);
|
|
482
496
|
const resolvedRead = readAll
|
|
483
497
|
? []
|
|
484
498
|
: hasExplicitRead
|
|
@@ -501,19 +515,17 @@ export const resolvePermissionProtocol = ({ permission, modules, }) => {
|
|
|
501
515
|
: normalizeStringList(Array.isArray(input.net) ? input.net : []);
|
|
502
516
|
const denyNet = normalizeStringList(input.denyNet);
|
|
503
517
|
const allowImportAll = input.allowImport === true;
|
|
504
|
-
const allowImport = allowImportAll
|
|
505
|
-
?
|
|
506
|
-
:
|
|
507
|
-
? input.allowImport
|
|
508
|
-
: [...DEFAULT_ALLOW_IMPORT_HOSTS]);
|
|
518
|
+
const allowImport = allowImportAll ? [] : normalizeStringList(Array.isArray(input.allowImport)
|
|
519
|
+
? input.allowImport
|
|
520
|
+
: [...DEFAULT_ALLOW_IMPORT_HOSTS]);
|
|
509
521
|
const envAllowAll = input.env?.allow === true;
|
|
510
|
-
const envAllow = envAllowAll
|
|
511
|
-
? []
|
|
512
|
-
: normalizeStringList(Array.isArray(input.env?.allow) ? input.env.allow : []);
|
|
522
|
+
const envAllow = envAllowAll ? [] : normalizeStringList(Array.isArray(input.env?.allow) ? input.env.allow : []);
|
|
513
523
|
const envDeny = normalizeStringList(input.env?.deny);
|
|
514
524
|
const legacyRunEnabled = input.node?.allowChildProcess === true ||
|
|
515
525
|
input.deno?.allowRun === true;
|
|
516
|
-
const runSource = hasOwn(input, "run")
|
|
526
|
+
const runSource = hasOwn(input, "run")
|
|
527
|
+
? input.run
|
|
528
|
+
: (legacyRunEnabled ? true : []);
|
|
517
529
|
const runAll = runSource === true;
|
|
518
530
|
const run = runAll
|
|
519
531
|
? []
|
|
@@ -526,9 +538,7 @@ export const resolvePermissionProtocol = ({ permission, modules, }) => {
|
|
|
526
538
|
? input.ffi
|
|
527
539
|
: (input.node?.allowAddons === true ? true : false);
|
|
528
540
|
const ffiAll = ffiSource === true;
|
|
529
|
-
const ffi = ffiAll
|
|
530
|
-
? []
|
|
531
|
-
: toUniquePathList(Array.isArray(ffiSource) ? ffiSource : undefined, cwd, home);
|
|
541
|
+
const ffi = ffiAll ? [] : toUniquePathList(Array.isArray(ffiSource) ? ffiSource : undefined, cwd, home);
|
|
532
542
|
const denyFfi = toUniquePathList(input.denyFfi, cwd, home);
|
|
533
543
|
const sysSource = input.sys;
|
|
534
544
|
const sysAll = sysSource === true;
|
package/src/runtime/pool.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { lock2 } from "../memory/lock.js";
|
|
|
4
4
|
import type { DebugOptions, DispatcherSettings, WorkerContext, WorkerData, WorkerSettings } from "../types.js";
|
|
5
5
|
import "../worker/loop.js";
|
|
6
6
|
import { type PayloadBufferOptions } from "../memory/payload-config.js";
|
|
7
|
-
export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload,
|
|
7
|
+
export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug, hostDebug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn, abortSignalCapacity, usesAbortSignal, }: {
|
|
8
8
|
list: string[];
|
|
9
9
|
ids: number[];
|
|
10
10
|
names: string[];
|
|
@@ -12,6 +12,7 @@ export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug
|
|
|
12
12
|
sab?: Sab;
|
|
13
13
|
thread: number;
|
|
14
14
|
debug?: DebugOptions;
|
|
15
|
+
hostDebug?: (message: string) => void;
|
|
15
16
|
totalNumberOfThread: number;
|
|
16
17
|
source?: string;
|
|
17
18
|
workerOptions?: WorkerSettings;
|
|
@@ -19,10 +20,7 @@ export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug
|
|
|
19
20
|
permission?: WorkerData["permission"];
|
|
20
21
|
host?: DispatcherSettings;
|
|
21
22
|
payload?: PayloadBufferOptions;
|
|
22
|
-
|
|
23
|
-
payloadMaxBytes?: number;
|
|
24
|
-
bufferMode?: PayloadBufferOptions["mode"];
|
|
25
|
-
maxPayloadBytes?: number;
|
|
23
|
+
bufferReferenceReturn?: "copy" | "borrow";
|
|
26
24
|
abortSignalCapacity?: number;
|
|
27
25
|
usesAbortSignal?: boolean;
|
|
28
26
|
}) => WorkerContext & {
|
package/src/runtime/pool.js
CHANGED
|
@@ -10,6 +10,7 @@ import { probeLockBufferTextCompat } from "../common/shared-buffer-text.js";
|
|
|
10
10
|
import { signalAbortFactory } from "../shared/abortSignal.js";
|
|
11
11
|
import { createLockControlCarpet } from "../memory/byte-carpet.js";
|
|
12
12
|
import { resolvePayloadBufferOptions, } from "../memory/payload-config.js";
|
|
13
|
+
import { createBufferReferenceReturnReleaseMessage } from "../connections/buffer-reference.js";
|
|
13
14
|
const WORKER_FATAL_MESSAGE_KEY = "__knittingWorkerFatal";
|
|
14
15
|
const isWorkerFatalMessage = (value) => !!value &&
|
|
15
16
|
typeof value === "object" &&
|
|
@@ -33,7 +34,7 @@ const withFixedPayloadConfig = (config) => ({
|
|
|
33
34
|
mode: "fixed",
|
|
34
35
|
payloadInitialBytes: config.payloadMaxByteLength,
|
|
35
36
|
});
|
|
36
|
-
export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload,
|
|
37
|
+
export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, hostDebug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn, abortSignalCapacity, usesAbortSignal, }) => {
|
|
37
38
|
const tsFileUrl = new URL(import.meta.url);
|
|
38
39
|
const poliWorker = RUNTIME_WORKER;
|
|
39
40
|
const resolvedWorkerOptions = serializeWorkerBootstrapData(withDefaultWorkerTimers(workerOptions));
|
|
@@ -47,9 +48,6 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
47
48
|
const processSharedMemorySettings = useProcessWorkerRuntime
|
|
48
49
|
? readProcessSharedMemorySettings(resolvedWorkerOptions)
|
|
49
50
|
: undefined;
|
|
50
|
-
if (debug?.logHref === true) {
|
|
51
|
-
console.log(tsFileUrl);
|
|
52
|
-
}
|
|
53
51
|
if (!useProcessWorkerRuntime && typeof poliWorker !== "function") {
|
|
54
52
|
throw new Error("Worker is not available in this runtime");
|
|
55
53
|
}
|
|
@@ -62,15 +60,7 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
62
60
|
return bytes > 0 ? bytes : undefined;
|
|
63
61
|
};
|
|
64
62
|
const basePayloadConfig = resolvePayloadBufferOptions({
|
|
65
|
-
options:
|
|
66
|
-
...payload,
|
|
67
|
-
mode: payload?.mode ?? bufferMode,
|
|
68
|
-
maxPayloadBytes: payload?.maxPayloadBytes ?? maxPayloadBytes,
|
|
69
|
-
payloadInitialBytes: payload?.payloadInitialBytes ??
|
|
70
|
-
sanitizeBytes(payloadInitialBytes),
|
|
71
|
-
payloadMaxByteLength: payload?.payloadMaxByteLength ??
|
|
72
|
-
sanitizeBytes(payloadMaxBytes),
|
|
73
|
-
},
|
|
63
|
+
options: payload,
|
|
74
64
|
});
|
|
75
65
|
const resolvedPayloadConfig = useProcessWorkerRuntime
|
|
76
66
|
? withFixedPayloadConfig(basePayloadConfig)
|
|
@@ -182,7 +172,6 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
182
172
|
: sab,
|
|
183
173
|
isMain: true,
|
|
184
174
|
thread,
|
|
185
|
-
debug,
|
|
186
175
|
});
|
|
187
176
|
const signalBox = signals;
|
|
188
177
|
const nativeNotifySignal = createProcessWorkerNativeSignalNotifier({
|
|
@@ -193,6 +182,11 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
193
182
|
lock,
|
|
194
183
|
returnLock,
|
|
195
184
|
abortSignals,
|
|
185
|
+
releaseBufferReferenceReturn: bufferReferenceReturn === "borrow"
|
|
186
|
+
? (token) => {
|
|
187
|
+
worker?.postMessage?.(createBufferReferenceReturnReleaseMessage(token));
|
|
188
|
+
}
|
|
189
|
+
: undefined,
|
|
196
190
|
});
|
|
197
191
|
const { enqueue, rejectAll, txIdle, } = queue;
|
|
198
192
|
const channelHandler = new ChannelHandler();
|
|
@@ -202,13 +196,18 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
202
196
|
channelHandler,
|
|
203
197
|
dispatcherOptions: host,
|
|
204
198
|
notifySignal: nativeNotifySignal,
|
|
205
|
-
//thread,
|
|
206
|
-
//debugSignal: debug?.logMain ?? false,
|
|
207
|
-
//perf,
|
|
208
199
|
});
|
|
209
200
|
channelHandler.open(check);
|
|
210
201
|
let worker;
|
|
211
202
|
const workerUrl = source ?? tsFileUrl;
|
|
203
|
+
const workerMode = useProcessWorkerRuntime
|
|
204
|
+
? "process"
|
|
205
|
+
: HAS_NODE_WORKER_THREADS
|
|
206
|
+
? "worker_threads"
|
|
207
|
+
: "worker";
|
|
208
|
+
hostDebug?.(`worker thread=${thread} mode=${workerMode}` +
|
|
209
|
+
`${processWorkerRuntime ? ` runtime=${processWorkerRuntime}` : ""}` +
|
|
210
|
+
` url=${String(workerUrl)}`);
|
|
212
211
|
const workerDataPayload = {
|
|
213
212
|
sab: signals.sab,
|
|
214
213
|
abortSignalSAB,
|
|
@@ -227,6 +226,7 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
227
226
|
lock: lockBuffers,
|
|
228
227
|
returnLock: returnLockBuffers,
|
|
229
228
|
payloadConfig: resolvedPayloadConfig,
|
|
229
|
+
bufferReferenceReturn,
|
|
230
230
|
permission,
|
|
231
231
|
};
|
|
232
232
|
const baseWorkerOptions = {
|
|
@@ -358,7 +358,7 @@ export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, total
|
|
|
358
358
|
Promise.resolve().then(check);
|
|
359
359
|
// Macro lane: dispatcher check is driven by the channel callback.
|
|
360
360
|
// channelHandler.notify();
|
|
361
|
-
// Use opView as a wake
|
|
361
|
+
// Use opView as a wake token in lock2 mode to avoid lost wakeups.
|
|
362
362
|
if (a_load(signalBox.rxStatus, 0) === 0) {
|
|
363
363
|
a_add(thisSignal, 0, 1);
|
|
364
364
|
notifySignal?.();
|
|
@@ -2,7 +2,8 @@ import { fileURLToPath as fileURLToPathCompat } from "node:url";
|
|
|
2
2
|
import { HEADER_SLOT_STRIDE_U32, LOCK_SECTOR_BYTE_LENGTH, LockBound, } from "../memory/lock.js";
|
|
3
3
|
import { createByteCarpet, getHeaderBlockByteLength, makeSharedBufferRegion, } from "../memory/byte-carpet.js";
|
|
4
4
|
import { RUNTIME } from "../common/runtime.js";
|
|
5
|
-
import {
|
|
5
|
+
import { debugHas } from "../debug/gate.js";
|
|
6
|
+
import { RUNTIME_POOL_DEPTH, RUNTIME_POOL_DEPTH_ENV, RUNTIME_PROCESS_WORKER_BOOT_ENV, RUNTIME_PROCESS_WORKER_BOOT_VERSION, RUNTIME_PROCESS_WORKER_ENV, } from "../common/worker-runtime.js";
|
|
6
7
|
import { getNodeBuiltinModule, getNodeProcess } from "../common/node-compat.js";
|
|
7
8
|
import { toSharedBufferRegion, } from "../common/shared-buffer-region.js";
|
|
8
9
|
import { createBunConnectionPrimitives } from "../connections/bun.js";
|
|
@@ -72,7 +73,7 @@ export const createProcessSharedMemoryAllocator = (debug) => {
|
|
|
72
73
|
addon = loadNodeNativeAddon(require, "knitting_shared_memory");
|
|
73
74
|
}
|
|
74
75
|
catch (error) {
|
|
75
|
-
if (debug
|
|
76
|
+
if (debugHas(debug, "lifecycle")) {
|
|
76
77
|
console.warn("Process-shared memory allocator unavailable; falling back to SharedArrayBuffer.", error);
|
|
77
78
|
}
|
|
78
79
|
return undefined;
|
|
@@ -100,6 +101,7 @@ const DEFAULT_NODE_BINARY = "node";
|
|
|
100
101
|
const DENO_PROCESS_WORKER_BOOT_ENV_ALLOW = [
|
|
101
102
|
RUNTIME_PROCESS_WORKER_ENV,
|
|
102
103
|
RUNTIME_PROCESS_WORKER_BOOT_ENV,
|
|
104
|
+
RUNTIME_POOL_DEPTH_ENV,
|
|
103
105
|
].join(",");
|
|
104
106
|
const DENO_PROCESS_WORKER_INTERNAL_FLAGS = [
|
|
105
107
|
`--allow-env=${DENO_PROCESS_WORKER_BOOT_ENV_ALLOW}`,
|
|
@@ -354,6 +356,7 @@ const currentProcessEnv = () => ({
|
|
|
354
356
|
const processWorkerEnv = (extra) => ({
|
|
355
357
|
...currentProcessEnv(),
|
|
356
358
|
[RUNTIME_PROCESS_WORKER_ENV]: "1",
|
|
359
|
+
[RUNTIME_POOL_DEPTH_ENV]: String(RUNTIME_POOL_DEPTH + 1),
|
|
357
360
|
...extra,
|
|
358
361
|
});
|
|
359
362
|
const processWorkerBootEnv = (bootPayload) => processWorkerEnv({
|