From 55a32fcab4cf032893a457e514dc8aad92bfe103 Mon Sep 17 00:00:00 2001 From: Iakov Gazizov Date: Fri, 12 Jun 2026 16:47:38 +0200 Subject: [PATCH] [emval] Gate val thread-affinity check on __EMSCRIPTEN_PTHREADS__ instead of _REENTRANT `_REENTRANT` is a POSIX convention that third-party libraries may define unconditionally for Unix-like targets (including Emscripten) without implying that the pthread runtime is actually present. When some translation units in a non-pthread build inherit `_REENTRANT` via transitive library dependencies and others don't, the `val::thread` field is only initialized in TUs that see `_REENTRANT`. Vals constructed without it have an uninitialized `thread` field; accessing them from TUs with `_REENTRANT` triggers a spurious assertion failure. `__EMSCRIPTEN_PTHREADS__` is set by the compiler only when `-pthread` is passed. It cannot be leaked by user code or build-system definitions, and precisely indicates that the pthread runtime is linked and `pthread_self()` returns meaningful values. Since `-pthread` always implies `_REENTRANT` anyway, there is no configuration where the assertion would be needed but `__EMSCRIPTEN_PTHREADS__` is absent. --- system/include/emscripten/val.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h index 197d8e8866302..dfb3e7e7c2b53 100644 --- a/system/include/emscripten/val.h +++ b/system/include/emscripten/val.h @@ -388,7 +388,7 @@ class EMBIND_VISIBILITY_DEFAULT val { } EM_VAL as_handle() const { -#ifdef _REENTRANT +#ifdef __EMSCRIPTEN_PTHREADS__ assert(pthread_equal(thread, pthread_self()) && "val accessed from wrong thread"); #endif return handle; @@ -568,7 +568,7 @@ class EMBIND_VISIBILITY_DEFAULT val { private: // takes ownership, assumes handle already incref'd and lives on the same thread explicit val(EM_VAL handle) : -#ifdef _REENTRANT +#ifdef __EMSCRIPTEN_PTHREADS__ thread(pthread_self()), #endif handle(handle) {}