this take care of doing that. // This way any thread can be linked to the main one. port.on('message', handleMessageFromThread); // Never block the thread on this port port.unref(); } break; case messageTypes.UNREGISTER_MAIN_THREAD_PORT: threadsPorts.get(message.threadId).close(); threadsPorts.delete(message.threadId); break; case messageTypes.SEND_MESSAGE_TO_WORKER: { // Send the message to the target thread const { source, destination, value, transferList, memory } = message; sendMessageToWorker(source, destination, value, transferList, memory); } break; } } function handleMessageFromMainThread(message) { switch (message.type) { case messageTypes.RECEIVE_MESSAGE_FROM_WORKER: receiveMessageFromWorker(message.source, message.value, message.memory); break; } } function sendMessageToWorker(source, destination, value, transferList, memory) { // We are on the main thread, we can directly process the message if (destination === 0) { receiveMessageFromWorker(source, value, memory); return; } // Search the port to the target thread const port = threadsPorts.get(destination); if (!port) { const status = new Int32Array(memory); AtomicsStore(status, WORKER_MESSAGING_RESULT_INDEX, WORKER_MESSAGING_RESULT_NO_LISTENERS); AtomicsStore(status, WORKER_MESSAGING_STATUS_INDEX, 1); AtomicsNotify(status, WORKER_MESSAGING_STATUS_INDEX, 1); return; } port.postMessage( { type: messageTypes.RECEIVE_MESSAGE_FROM_WORKER, source, destination, value, memory, }, transferList, ); } function receiveMessageFromWorker(source, value, memory) { let response = WORKER_MESSAGING_RESULT_NO_LISTENERS; try { if (process.emit('workerMessage', value, source)) { response = WORKER_MESSAGING_RESULT_DELIVERED; } } catch { response = WORKER_MESSAGING_RESULT_LISTENER_ERROR; } // Populate the result const status = new Int32Array(memory); AtomicsStore(status, WORKER_MESSAGING_RESULT_INDEX, response); AtomicsStore(status, WORKER_MESSAGING_STATUS_INDEX, 1); AtomicsNotify(status, WORKER_MESSAGING_STATUS_INDEX, 1); } function createMainThreadPort(threadId) { // Create a channel that links the new thread to the main thread const { port1: mainThreadPortToMain, port2: mainThreadPortToThread, } = new MessageChannel(); const registrationMessage = { type: messageTypes.REGISTER_MAIN_THREAD_PORT, threadId, port: mainThreadPortToMain, }; if (isMainThread) { handleMessageFromThread(registrationMessage); } else { mainThreadPort.postMessage(registrationMessage, [mainThreadPortToMain]); } return mainThreadPortToThread; } function destroyMainThreadPort(threadId) { const unregistrationMessage = { type: messageTypes.UNREGISTER_MAIN_THREAD_PORT, threadId, }; if (isMainThread) { handleMessageFromThread(unregistrationMessage); } else { mainThreadPort.postMessage(unregistrationMessage); } } function setupMainThreadPort(port) { mainThreadPort = port; mainThreadPort.on('message', handleMessageFromMainThread); // Never block the process on this port mainThreadPort.unref(); } async function postMessageToThread(threadId, value, transferList, timeout) { if (typeof transferList === 'number' && typeof timeout === 'undefined') { timeout = transferList; transferList = []; } if (typeof timeout !== 'undefined') { validateNumber(timeout, 'timeout', 0); } if (threadId === currentThreadId) { throw new ERR_WORKER_MESSAGING_SAME_THREAD(); } const memory = new SharedArrayBuffer(WORKER_MESSAGING_SHARED_DATA); const status = new Int32Array(memory); const promise = AtomicsWaitAsync(status, WORKER_MESSAGING_STATUS_INDEX, 0, timeout).value; const message = { type: messageTypes.SEND_MESSAGE_TO_WORKER, source: currentThreadId, destination: threadId, value, memory, transferList, }; if (isMainThread) { handleMessageFromThread(message); } else { mainThreadPort.postMessage(message, transferList); } // Wait for the response const response = await promise; if (response === 'timed-out') { throw new ERR_WORKER_MESSAGING_TIMEOUT(); } else if (status[WORKER_MESSAGING_RESULT_INDEX] === WORKER_MESSAGING_RESULT_NO_LISTENERS) { throw new ERR_WORKER_MESSAGING_FAILED(); } else if (status[WORKER_MESSAGING_RESULT_INDEX] === WORKER_MESSAGING_RESULT_LISTENER_ERROR) { throw new ERR_WORKER_MESSAGING_ERRORED(); } } module.exports = { createMainThreadPort, destroyMainThreadPort, setupMainThreadPort, postMessageToThread, };