Skip to content

Fix Asyncify.handleAsync conflict with PROXY_SYNC_ASYNC#26513

Open
thiblahute wants to merge 1 commit intoemscripten-core:mainfrom
thiblahute:ppoll_proxy
Open

Fix Asyncify.handleAsync conflict with PROXY_SYNC_ASYNC#26513
thiblahute wants to merge 1 commit intoemscripten-core:mainfrom
thiblahute:ppoll_proxy

Conversation

@thiblahute
Copy link
Copy Markdown
Contributor

@thiblahute thiblahute commented Mar 21, 2026

When in a proxied context, skip the Asyncify unwind and call
startAsync() directly, letting the proxy mechanism handle the
async return.

This already affects __syscall_poll and would also affect the new
__syscall_ppoll.

Copy link
Copy Markdown
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

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

Did you see I landed support for ppoll and pselect yesterday in #26482. Hopefully this change is not needed after that?

@thiblahute
Copy link
Copy Markdown
Contributor Author

thiblahute commented Mar 21, 2026

Thanks! Yes, I just saw #26482 landed ppoll support - I've rebased and dropped the ppoll commit. The remaining change here fixes a pre-existing bug in Asyncify.handleAsync when used with PROXY_SYNC_ASYNC: the test confirms it reproduces with the upstream ppoll implementation too (without the fix, you get rtn.then is not a function because handleAsync does an Asyncify unwind instead of returning a Promise in the proxied context).

@thiblahute thiblahute changed the title Implement ppoll() in JS and fix Asyncify/PROXY_SYNC_ASYNC conflict Fix Asyncify.handleAsync conflict with PROXY_SYNC_ASYNC Mar 21, 2026
@thiblahute thiblahute force-pushed the ppoll_proxy branch 6 times, most recently from 5089fe8 to 4c3d00b Compare March 23, 2026 15:22
@thiblahute thiblahute force-pushed the ppoll_proxy branch 3 times, most recently from c4ceddb to e414ec8 Compare March 23, 2026 17:35
@thiblahute thiblahute force-pushed the ppoll_proxy branch 4 times, most recently from 752c3e2 to 8fe0d22 Compare April 1, 2026 20:00
# require_pthreads can fail when require_jspi selects d8 (which doesn't
# support pthreads). Convert to skip since the test needs both.
if not any(engine_is_node(e) or engine_is_bun(e) for e in self.js_engines):
self.skipTest('no JS engine capable of running pthreads')
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.

I don't love having these extra 4 lines here. Especially with the automatic skip thing (we try not to auto-skip stuff in general, but force folks to opt into skipping this kind of thing)

It seems like there is some kind of bad interaction here between require_pthreads and with_asyncify_and_jspi? Doers it occur whichever way around you put the decorators>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, I tried both ways and I ended up with a "conflicting engine" on the CI as it was trying to use d8 which doesn't support pthread

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.

OK, this seems like something we should fix, but it doesn't have to be for this PR

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK, what do you want me to do get to get that one in a shape you are happy with?

When a JS library function has both __proxy:'sync' and __async:'auto',
the compiler generates an Asyncify.handleAsync wrapper.  When called
from the PROXY_SYNC_ASYNC path on the main thread, handleAsync
triggers an Asyncify unwind instead of returning a Promise, causing
"rtn.then is not a function" in the proxy infrastructure.

Fix by generating a PThread.currentProxiedOperationCallerThread check
in handleAsyncFunction (jsifier.mjs): when in a proxied context, call
the inner function directly and skip the Asyncify unwind, letting the
proxy mechanism handle the async return.
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.

2 participants