diff --git a/src/libs/shared/shared/threading/Utility.cpp b/src/libs/shared/shared/threading/Utility.cpp index 1ee985ccf..ec69b7ef2 100644 --- a/src/libs/shared/shared/threading/Utility.cpp +++ b/src/libs/shared/shared/threading/Utility.cpp @@ -14,11 +14,19 @@ #include #include +#if defined __APPLE__ + #include +#endif + #ifdef _WIN32 #include #include #elif defined TARGET_OS_MAC #include +#include +#include +#include +#include #elif defined __linux__ || defined __unix__ #include #include @@ -92,11 +100,36 @@ Result set_name([[maybe_unused]] auto& handle, const char* name) { FreeLibrary(lib); #elif defined TARGET_OS_MAC - auto ret = pthread_setname_np(name); + static std::atomic desiredThreadName{name}; + static std::atomic ret{KERN_FAILURE}; + static std::atomic busy{true}; + + // Define the signal handler + const auto threadNameHandler = +[](int /*signum*/) -> void { + const char* name = desiredThreadName.load(std::memory_order_acquire); + if (name != nullptr) { + ret.store(pthread_setname_np(name), std::memory_order_release); + } + busy.store(false, std::memory_order_release); + }; - if(ret) { - throw std::runtime_error("Unable to set thread name, error code" + std::to_string(ret)); + // Install the signal handler once for the process. + static std::atomic_flag handlerInstalled = ATOMIC_FLAG_INIT; + if (!handlerInstalled.test_and_set(std::memory_order_acquire)) { + signal(SIGUSR1, threadNameHandler); } + + // Send SIGUSR1 to the target thread so it runs the signal handler. + if (pthread_kill(handle, SIGUSR1) != 0) { + throw std::runtime_error("Unable to send signal handler to thread, error code " + std::to_string(ret)); + } + + while (busy == true) {std::this_thread::yield();} + + if (ret.load(std::memory_order_acquire) != KERN_SUCCESS) { + throw std::runtime_error("Unable to set thread name, error code " + std::to_string(ret)); + } + #elif defined __linux__ || defined __unix__ auto ret = pthread_setname_np(handle, name); @@ -109,23 +142,13 @@ Result set_name([[maybe_unused]] auto& handle, const char* name) { } Result set_name(std::jthread& thread, const char* name) { -#ifndef TARGET_OS_MAC const auto handle = thread.native_handle(); return set_name(handle, name); -#else - #pragma message WARN("Setting thread names is not implemented for this platform. Implement it, please!") - return Result::unsupported; -#endif } Result set_name(std::thread& thread, const char* name) { -#ifndef TARGET_OS_MAC const auto handle = thread.native_handle(); return set_name(handle, name); -#else - #pragma message WARN("Setting thread names is not implemented for this platform. Implement it, please!") - return Result::unsupported; -#endif } Result set_name(const char* name) { @@ -228,5 +251,4 @@ unsigned int hardware_concurrency() { return hardware_concurrency(nullptr); } - } // thread, ember \ No newline at end of file