Skip to content

Commit 02ef167

Browse files
authored
Add _emscripten_thread_is_valid helper. NFC (#17020)
1 parent 139bced commit 02ef167

File tree

4 files changed

+16
-3
lines changed

4 files changed

+16
-3
lines changed

system/lib/libc/musl/src/thread/pthread_detach.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33

44
static int __pthread_detach(pthread_t t)
55
{
6+
#ifdef __EMSCRIPTEN__
67
// XXX EMSCRIPTEN: Add check for invalid (already joined) thread. Again
78
// for the benefit of the conformance tests.
8-
if (t->self != t)
9+
if (!_emscripten_thread_is_valid(t))
910
return ESRCH;
11+
#endif
1012
/* If the cas fails, detach state is either already-detached
1113
* or exiting/exited, and pthread_join will trap or cleanup. */
1214
if (a_cas(&t->detach_state, DT_JOINABLE, DT_DETACHED) != DT_JOINABLE)

system/lib/libc/musl/src/thread/pthread_join.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ static int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec
1616
#ifdef __EMSCRIPTEN__
1717
// Attempt to join a thread which does not point to a valid thread, or
1818
// does not exist anymore.
19-
if (t->self != t) return ESRCH;
19+
if (!_emscripten_thread_is_valid(t)) return ESRCH;
2020
// Thread is attempting to join to itself. Already detached threads are
2121
// handled below by returning EINVAL instead.
22-
// TODO: The detached check here is just to satisfy the `other.test_{proxy,main}_pthread_join_detach` tests.
22+
// TODO: The detached check here is just to satisfy the
23+
// `other.test_{proxy,main}_pthread_join_detach` tests.
2324
if (t->detach_state != DT_DETACHED && __pthread_self() == t) return EDEADLK;
2425
#endif
2526
int state, cs, r = 0;

system/lib/pthread/library_pthread.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,10 @@ int emscripten_dispatch_to_thread_async_(pthread_t target_thread,
657657
return ret;
658658
}
659659

660+
int _emscripten_thread_is_valid(pthread_t thread) {
661+
return thread->self == thread;
662+
}
663+
660664
static void *dummy_tsd[1] = { 0 };
661665
weak_alias(dummy_tsd, __pthread_tsd_main);
662666

system/lib/pthread/threading_internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ typedef struct thread_profiler_block {
9999
void __emscripten_init_main_thread_js(void* tb);
100100
void _emscripten_thread_profiler_enable();
101101

102+
// Checks certain structural invariants. This allows us to detect when
103+
// already-freed threads are used in some APIs. Technically this is undefined
104+
// behaviour, but we have a couple of places where we add these checks so that
105+
// we can pass more of the posixtest suite that vanilla musl.
106+
int _emscripten_thread_is_valid(pthread_t thread);
107+
102108
#ifdef NDEBUG
103109
#define emscripten_set_current_thread_status(newStatus)
104110
#define emscripten_conditional_set_current_thread_status(expectedStatus, newStatus)

0 commit comments

Comments
 (0)