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,
};
