diff --git a/src/common.cpp b/src/common.cpp index ccfc0764f..bd4fa8e3c 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -55,6 +55,7 @@ #include "flog.h" #include "future_feature_flags.h" #include "global_safety.h" +#include "iothread.h" #include "proc.h" #include "signal.h" #include "wildcard.h" @@ -64,8 +65,6 @@ constexpr wint_t NOT_A_WCHAR = static_cast(WEOF); struct termios shell_modes; -/// This allows us to determine if we're running on the main thread -static std::atomic thread_id{0}; /// This allows us to notice when we've forked. static relaxed_atomic_bool_t is_forked_proc{false}; /// This allows us to bypass the main thread checks @@ -2279,10 +2278,10 @@ extern "C" { } void set_main_thread() { - // Just call is_main_thread() once to force increment of thread_id. - bool x = is_main_thread(); - assert(x && "set_main_thread should be main thread"); - (void)x; + // Just call thread_id() once to force increment of thread_id. + uint64_t tid = thread_id(); + assert(tid == 1 && "main thread should have thread ID 1"); + (void)tid; } void configure_thread_assertions_for_testing() { thread_asserts_cfg_for_testing = true; } @@ -2310,10 +2309,7 @@ void restore_term_foreground_process_group() { } } -bool is_main_thread() { - static thread_local int local_thread_id = thread_id++; - return local_thread_id == 0; -} +bool is_main_thread() { return thread_id() == 1; } void assert_is_main_thread(const char *who) { if (!is_main_thread() && !thread_asserts_cfg_for_testing) { diff --git a/src/iothread.cpp b/src/iothread.cpp index f206e776a..43854dcc8 100644 --- a/src/iothread.cpp +++ b/src/iothread.cpp @@ -357,6 +357,8 @@ bool make_pthread(pthread_t *result, void *(*func)(void *), void *param) { using void_func_t = std::function; static void *func_invoker(void *param) { + // Acquire a thread id for this thread. + (void)thread_id(); void_func_t *vf = static_cast(param); (*vf)(); delete vf; @@ -373,3 +375,15 @@ bool make_pthread(pthread_t *result, void_func_t &&func) { delete vf; return false; } + +static uint64_t next_thread_id() { + // Note 0 is an invalid thread id. + static owning_lock s_last_thread_id{}; + auto tid = s_last_thread_id.acquire(); + return ++*tid; +} + +uint64_t thread_id() { + static thread_local uint64_t tl_tid = next_thread_id(); + return tl_tid; +} diff --git a/src/iothread.h b/src/iothread.h index 39d99e539..70a5a2c58 100644 --- a/src/iothread.h +++ b/src/iothread.h @@ -82,4 +82,8 @@ void iothread_perform_on_main(std::function &&func); bool make_pthread(pthread_t *result, void *(*func)(void *), void *param); bool make_pthread(pthread_t *result, std::function &&func); +/// \returns a thread ID for this thread. +/// Thread IDs are never repeated. +uint64_t thread_id(); + #endif