* Ring buffer writer (used by main thread)
| 56 | * Ring buffer writer (used by main thread) |
| 57 | */ |
| 58 | class RingBufferWriter { |
| 59 | constructor(sharedBuffer) { |
| 60 | this.buffer = sharedBuffer; |
| 61 | this.int32 = new Int32Array(sharedBuffer); |
| 62 | this.uint8 = new Uint8Array(sharedBuffer); |
| 63 | this.dataView = new DataView(sharedBuffer); |
| 64 | } |
| 65 | |
| 66 | /** |
| 67 | * Get available space in the ring buffer |
| 68 | */ |
| 69 | availableSpace() { |
| 70 | const head = Atomics.load(this.int32, NET_HEAD_INDEX); |
| 71 | const tail = Atomics.load(this.int32, NET_TAIL_INDEX); |
| 72 | |
| 73 | if (head >= tail) { |
| 74 | // Head is ahead of tail: free space is (size - head) + tail - 1 |
| 75 | return (NET_RING_SIZE - head) + tail - 1; |
| 76 | } else { |
| 77 | // Tail is ahead: free space is tail - head - 1 |
| 78 | return tail - head - 1; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | /** |
| 83 | * Check if buffer has enough space (non-blocking) |
| 84 | * @param {number} needed - Bytes needed |
| 85 | * @returns {boolean} |
| 86 | */ |
| 87 | hasSpace(needed) { |
| 88 | return this.availableSpace() >= needed; |
| 89 | } |
| 90 | |
| 91 | /** |
| 92 | * Signal the worker to wake up and process data |
| 93 | * Call this when buffer is full to wake the worker to drain it |
| 94 | */ |
| 95 | signalWorker() { |
| 96 | Atomics.add(this.int32, IO_READY_INDEX, 1); |
| 97 | Atomics.notify(this.int32, IO_READY_INDEX); |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * Write a network message to the ring buffer |
| 102 | * @param {number} type - Message type (NET_MSG_*) |
| 103 | * @param {Uint8Array|Buffer} payload - Message payload |
| 104 | * @returns {boolean} - True if written, false if no space |
| 105 | */ |
| 106 | writeMessage(type, payload) { |
| 107 | const msgLen = 3 + payload.length; // 2 bytes length + 1 byte type + payload |
| 108 | |
| 109 | if (this.availableSpace() < msgLen) { |
| 110 | return false; // No space |
| 111 | } |
| 112 | |
| 113 | let head = Atomics.load(this.int32, NET_HEAD_INDEX); |
| 114 | const ringStart = NET_RING_OFFSET; |
| 115 |
nothing calls this directly
no outgoing calls
no test coverage detected