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.

@sbc100
sbc100 force-pushed the fix_bun_pthreads branch 3 times, most recently from cc426e2 to 93357eb Compare August 26, 2026 17:46
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 defined,
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
@kleisauke

Copy link
Copy Markdown
Collaborator

I suspect this will be fixed in Bun via PR oven-sh/bun#35655.

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

4 participants