Skip to content

Fix Bun 1.4 + pthreads by always bridging parentPort in worker threads - #27582

Open
sbc100 wants to merge 1 commit into
emscripten-core:mainfrom
sbc100:fix_bun_pthreads
Open

Fix Bun 1.4 + pthreads by always bridging parentPort in worker threads#27582
sbc100 wants to merge 1 commit into
emscripten-core:mainfrom
sbc100:fix_bun_pthreads

Conversation

@sbc100

@sbc100 sbc100 commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

In #25947, a check for !globalThis.postMessage was added before wiring parentPort.on('message') -> globalThis.onmessage and globalThis.postMessage = (msg) => parentPort.postMessage(msg).

However, in Bun 1.4+, node:worker_threads deliveries are isolated to parentPort (they are no longer automatically routed to globalThis.onmessage), while globalThis.postMessage remains defined on the global object. Because globalThis.postMessage was truthy, Emscripten skipped hooking parentPort.on('message'), leaving worker threads unresponsive to initialization messages from the main thread.

Removing the if (!globalThis.postMessage) guard ensures parentPort is always correctly wired whenever running in a Node-style worker thread.

Fixes: #27580

@sbc100
sbc100 requested a review from dschuff August 20, 2026 23:51
var worker_threads = await import('node:worker_threads');
globalThis.Worker = worker_threads.Worker;
var parentPort = worker_threads.parentPort;
// Deno and Bun already have `postMessage` defined on the global scope and

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this isn't a problem for deno?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems not no.

Sadly this change does beak bun < 1.4 (since it ends up delivering messages twice).. but I'm not sure we care about back compat at this point.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the original reason for the guard was fixed in denoland/deno#32596.

In emscripten-core#25947, a check for `!globalThis.postMessage` was added before
wiring `parentPort.on('message') -> globalThis.onmessage` and
`globalThis.postMessage = (msg) => parentPort.postMessage(msg)`.

However, in Bun 1.4+, `node:worker_threads` deliveries are isolated to
`parentPort` (they are no longer automatically routed to
`globalThis.onmessage`), while `globalThis.postMessage` remains defined
on the global object. Because `globalThis.postMessage` was truthy,
Emscripten skipped hooking `parentPort.on('message')`, leaving worker
threads unresponsive to initialization messages from the main thread.

Removing the `if (!globalThis.postMessage)` guard ensures `parentPort`
is always correctly wired whenever running in a Node-style worker
thread.

Fixes: emscripten-core#27580
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Updating from bun 1.3 to 1.4 seems to have broken core0.test_em_js_pthreads_dylink

3 participants