Make it impossible to have more than one main thread.
(cherry picked from commit 2ff661cd8d9b229b6a8d0e64ccd9cb52e92c1315)
This commit is contained in:
1 parent
f9aa898e74
commit
17cd7dbac7
5 files changed
+47
-9
No files matched your search
@@ -88,6 +88,20 @@ void Thread::wait_to_finish() {
|
||||
id = UNASSIGNED_ID;
|
||||
}
|
||||
|
||||
void Thread::make_main_thread() {
|
||||
if (caller_id == MAIN_ID) {
|
||||
return; // We're already the main thread
|
||||
}
|
||||
CRASH_COND_MSG(!is_main_thread_assigned.set_if_clear(), "A second thread attempted to become the main thread.");
|
||||
caller_id = MAIN_ID;
|
||||
}
|
||||
|
||||
void Thread::release_main_thread() {
|
||||
CRASH_COND_MSG(caller_id != MAIN_ID, "Trying to release main thread from a thread that isn't main.");
|
||||
CRASH_COND(!is_main_thread_assigned.clear_if_set());
|
||||
caller_id = id_counter.increment();
|
||||
}
|
||||
|
||||
Error Thread::set_name(const String &p_name) {
|
||||
if (platform_functions.set_name) {
|
||||
return platform_functions.set_name(p_name);
|
||||
|
||||
+5
-6
@@ -107,15 +107,13 @@ private:
|
||||
|
||||
ID id = UNASSIGNED_ID;
|
||||
|
||||
static inline SafeFlag is_main_thread_assigned{ false };
|
||||
static SafeNumeric<uint64_t> id_counter;
|
||||
static thread_local ID caller_id;
|
||||
THREADING_NAMESPACE::thread thread;
|
||||
|
||||
static void callback(ID p_caller_id, const Settings &p_settings, Thread::Callback p_callback, void *p_userdata);
|
||||
|
||||
static void make_main_thread() { caller_id = MAIN_ID; }
|
||||
static void release_main_thread() { caller_id = id_counter.increment(); }
|
||||
|
||||
public:
|
||||
static void _set_platform_functions(const PlatformFunctions &p_functions);
|
||||
|
||||
@@ -130,6 +128,8 @@ public:
|
||||
_FORCE_INLINE_ static ID get_main_id() { return MAIN_ID; }
|
||||
|
||||
_FORCE_INLINE_ static bool is_main_thread() { return caller_id == MAIN_ID; } // Gain a tiny bit of perf here because there is no need to validate caller_id here, because only main thread will be set as 1.
|
||||
static void make_main_thread();
|
||||
static void release_main_thread();
|
||||
|
||||
static Error set_name(const String &p_name);
|
||||
|
||||
@@ -182,9 +182,6 @@ private:
|
||||
|
||||
static PlatformFunctions platform_functions;
|
||||
|
||||
static void make_main_thread() {}
|
||||
static void release_main_thread() {}
|
||||
|
||||
public:
|
||||
static void _set_platform_functions(const PlatformFunctions &p_functions);
|
||||
|
||||
@@ -193,6 +190,8 @@ public:
|
||||
_FORCE_INLINE_ static ID get_main_id() { return MAIN_ID; }
|
||||
|
||||
_FORCE_INLINE_ static bool is_main_thread() { return true; }
|
||||
static void make_main_thread() {}
|
||||
static void release_main_thread() {}
|
||||
|
||||
static Error set_name(const String &p_name) { return ERR_UNAVAILABLE; }
|
||||
|
||||
|
||||
@@ -62,6 +62,20 @@ void *Thread::thread_callback(void *p_data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Thread::make_main_thread() {
|
||||
if (caller_id == MAIN_ID) {
|
||||
return; // We're already the main thread
|
||||
}
|
||||
CRASH_COND_MSG(!is_main_thread_assigned.set_if_clear(), "A second thread attempted to become the main thread.");
|
||||
caller_id = MAIN_ID;
|
||||
}
|
||||
|
||||
void Thread::release_main_thread() {
|
||||
CRASH_COND_MSG(caller_id != MAIN_ID, "Trying to release main thread from a thread that isn't main.");
|
||||
CRASH_COND(!is_main_thread_assigned.clear_if_set());
|
||||
caller_id = id_counter.increment();
|
||||
}
|
||||
|
||||
Error Thread::set_name(const String &p_name) {
|
||||
int err = pthread_setname_np(p_name.utf8().get_data());
|
||||
return err == 0 ? OK : ERR_INVALID_PARAMETER;
|
||||
|
||||
@@ -76,14 +76,12 @@ private:
|
||||
ID id = UNASSIGNED_ID;
|
||||
pthread_t pthread;
|
||||
|
||||
static inline SafeFlag is_main_thread_assigned{ false };
|
||||
static SafeNumeric<uint64_t> id_counter;
|
||||
static thread_local ID caller_id;
|
||||
|
||||
static void *thread_callback(void *p_data);
|
||||
|
||||
static void make_main_thread() { caller_id = MAIN_ID; }
|
||||
static void release_main_thread() { caller_id = id_counter.increment(); }
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ static void yield() { pthread_yield_np(); }
|
||||
|
||||
@@ -96,6 +94,8 @@ public:
|
||||
_FORCE_INLINE_ static ID get_main_id() { return MAIN_ID; }
|
||||
|
||||
_FORCE_INLINE_ static bool is_main_thread() { return caller_id == MAIN_ID; }
|
||||
static void make_main_thread();
|
||||
static void release_main_thread();
|
||||
|
||||
static Error set_name(const String &p_name);
|
||||
|
||||
|
||||
@@ -745,6 +745,7 @@ void Main::test_cleanup() {}
|
||||
// are initialized here. This also combines `Main::setup2()` initialization.
|
||||
Error Main::test_setup() {
|
||||
Thread::make_main_thread();
|
||||
|
||||
set_current_thread_safe_for_nodes(true);
|
||||
|
||||
OS::get_singleton()->initialize();
|
||||
@@ -884,6 +885,8 @@ Error Main::test_setup() {
|
||||
void Main::test_cleanup() {
|
||||
ERR_FAIL_COND(!_start_success);
|
||||
|
||||
Thread::make_main_thread();
|
||||
|
||||
// Printing in the usual way can become problematic during/after cleanup.
|
||||
CoreGlobals::print_ready = false;
|
||||
|
||||
@@ -971,6 +974,8 @@ void Main::test_cleanup() {
|
||||
unregister_core_types();
|
||||
|
||||
OS::get_singleton()->finalize_core();
|
||||
|
||||
Thread::release_main_thread();
|
||||
}
|
||||
#endif // TESTS_ENABLED
|
||||
|
||||
@@ -3004,6 +3009,8 @@ error:
|
||||
OS::get_singleton()->finalize_core();
|
||||
locale = String();
|
||||
|
||||
Thread::release_main_thread();
|
||||
|
||||
return exit_err;
|
||||
}
|
||||
|
||||
@@ -5210,6 +5217,8 @@ void Main::force_redraw() {
|
||||
* The order matters as some of those steps are linked with each other.
|
||||
*/
|
||||
void Main::cleanup(bool p_force) {
|
||||
Thread::make_main_thread();
|
||||
|
||||
GodotProfileZone("cleanup");
|
||||
OS::get_singleton()->benchmark_begin_measure("Shutdown", "Main::Cleanup");
|
||||
if (!p_force) {
|
||||
@@ -5395,4 +5404,6 @@ void Main::cleanup(bool p_force) {
|
||||
OS::get_singleton()->benchmark_dump();
|
||||
|
||||
OS::get_singleton()->finalize_core();
|
||||
|
||||
Thread::release_main_thread();
|
||||
}
|
||||
Reference in new issue
Block a user