From 9887c2b4f0b1e0c1ba8d575669d3c7093854d584 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Sun, 7 Mar 2021 00:17:20 +0200 Subject: Improve thread IDs to avoid collisions with threads not created by the Godot API. --- core/os/thread.cpp | 24 ++++++++++++++---------- core/os/thread.h | 5 +++-- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/core/os/thread.cpp b/core/os/thread.cpp index aea370787d..f1fcfdf7e1 100644 --- a/core/os/thread.cpp +++ b/core/os/thread.cpp @@ -41,9 +41,13 @@ void (*Thread::set_priority_func)(Thread::Priority) = nullptr; void (*Thread::init_func)() = nullptr; void (*Thread::term_func)() = nullptr; -Thread::ID Thread::main_thread_id = 1; -SafeNumeric Thread::last_thread_id{ 1 }; -thread_local Thread::ID Thread::caller_id = 1; +uint64_t Thread::_thread_id_hash(const std::thread::id &p_t) { + static std::hash hasher; + return hasher(p_t); +} + +Thread::ID Thread::main_thread_id = _thread_id_hash(std::this_thread::get_id()); +thread_local Thread::ID Thread::caller_id = _thread_id_hash(std::this_thread::get_id()); void Thread::_set_platform_funcs( Error (*p_set_name_func)(const String &), @@ -57,7 +61,7 @@ void Thread::_set_platform_funcs( } void Thread::callback(Thread *p_self, const Settings &p_settings, Callback p_callback, void *p_userdata) { - Thread::caller_id = p_self->id; + Thread::caller_id = _thread_id_hash(p_self->thread.get_id()); if (set_priority_func) { set_priority_func(p_settings.priority); } @@ -73,7 +77,7 @@ void Thread::callback(Thread *p_self, const Settings &p_settings, Callback p_cal } void Thread::start(Thread::Callback p_callback, void *p_user, const Settings &p_settings) { - if (id != 0) { + if (id != _thread_id_hash(std::thread::id())) { #ifdef DEBUG_ENABLED WARN_PRINT("A Thread object has been re-started without wait_to_finish() having been called on it. Please do so to ensure correct cleanup of the thread."); #endif @@ -81,22 +85,22 @@ void Thread::start(Thread::Callback p_callback, void *p_user, const Settings &p_ std::thread empty_thread; thread.swap(empty_thread); } - id = last_thread_id.increment(); std::thread new_thread(&Thread::callback, this, p_settings, p_callback, p_user); thread.swap(new_thread); + id = _thread_id_hash(thread.get_id()); } bool Thread::is_started() const { - return id != 0; + return id != _thread_id_hash(std::thread::id()); } void Thread::wait_to_finish() { - if (id != 0) { + if (id != _thread_id_hash(std::thread::id())) { ERR_FAIL_COND_MSG(id == get_caller_id(), "A Thread can't wait for itself to finish."); thread.join(); std::thread empty_thread; thread.swap(empty_thread); - id = 0; + id = _thread_id_hash(std::thread::id()); } } @@ -109,7 +113,7 @@ Error Thread::set_name(const String &p_name) { } Thread::~Thread() { - if (id != 0) { + if (id != _thread_id_hash(std::thread::id())) { #ifdef DEBUG_ENABLED WARN_PRINT("A Thread object has been destroyed without wait_to_finish() having been called on it. Please do so to ensure correct cleanup of the thread."); #endif diff --git a/core/os/thread.h b/core/os/thread.h index 76f5be182e..599585051f 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -62,9 +62,10 @@ private: friend class Main; static ID main_thread_id; - static SafeNumeric last_thread_id; - ID id = 0; + static uint64_t _thread_id_hash(const std::thread::id &p_t); + + ID id = _thread_id_hash(std::thread::id()); static thread_local ID caller_id; std::thread thread; -- cgit v1.2.3