Skip to content

Fix race condition in assigning the pthread_t object in main thread - #25209

Merged
juj merged 3 commits into
emscripten-core:mainfrom
juj:fix_thread_ptr_assignment_race
Sep 9, 2025
Merged

juj merged 3 commits into
emscripten-core:mainfrom
juj:fix_thread_ptr_assignment_race

Conversation

@juj

@juj juj commented Sep 7, 2025

Copy link
Copy Markdown
Collaborator

Fix race condition in assigning the pthread_t object in main thread, when creating a pthread. Fixes #25026.

Also reduce the stress test case for test_stress_pthread_proxying so that it runs faster and reproduces more often.

Comment thread system/lib/pthread/pthread_create.c Outdated
// Assign the pthread_t object over immediately, so that by the time pthread_create_js()
// is dispatched to a pthread and the pthread main runs, the value will be visible to
// the thread to examine.
__atomic_store_n(res, new, __ATOMIC_SEQ_CST);

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.

In the musl codebase you can/should use the a_store macro instead I think.

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.

This is not musl codebase file? This is our own, no?

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.

This file uses the musl atomics convetions, and its at-least-in-part based on the musl version of the same code. See all the a_store, a_cas and __wait calls that exist already.

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.

a_store only assigns an integer, so it would splice the pointer in a 64-bit build.

Would you like

#ifdef __wasm64__
  a_store_l((long*)res, (long)new);
#else
  a_store((int*)res, (int)new);
#endif

instead?

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.

This makes me wonder how musl deals with this issue.

The core here is heavily based on ./system/lib/libc/musl/src/thread/pthread_create.c including the final *res = new; assignment.

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.

LGTM then with an extra comment about why we are not using a_store here.

I'm still curious why the pointer needs to be assigned though, isn't it enough for the struct pthread to be populated correctly? Where does the target thread depend on *res* being set?

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.

(Also, would the standard C11 atomic_store work here? https://en.cppreference.com/w/c/atomic/atomic_store)

@juj
juj force-pushed the fix_thread_ptr_assignment_race branch from d9e3154 to b051e2c Compare September 9, 2025 17:43
Comment thread system/lib/pthread/pthread_create.c Outdated

// Assign the pthread_t object over immediately, so that by the time pthread_create_js()
// is dispatched to a pthread and the pthread main runs, the value will be visible to
// the thread to examine.

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.

Can we move this to line 250?

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.

ok

Comment thread system/lib/pthread/pthread_create.c
@juj
juj merged commit fc02a77 into emscripten-core:main Sep 9, 2025
3 of 14 checks passed
inolen pushed a commit to inolen/emscripten that referenced this pull request Feb 13, 2026
…mscripten-core#25209)

Fix race condition in assigning the pthread_t object in main thread,
when creating a pthread. Fixes emscripten-core#25026.

Also reduce the stress test case for `test_stress_pthread_proxying` so
that it runs faster and reproduces more often.
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.

test_pthread_proxying is flaky

2 participants