@@ -1392,17 +1392,14 @@ String GDScript::debug_get_script_name(const Ref<Script> &p_script) {
13921392#endif
13931393
13941394thread_local GDScript::UpdatableFuncPtr GDScript::func_ptrs_to_update_thread_local;
1395- GDScript::UpdatableFuncPtr *GDScript::func_ptrs_to_update_main_thread = &func_ptrs_to_update_thread_local;
13961395
1397- List<GDScript::UpdatableFuncPtrElement>::Element *GDScript::_add_func_ptr_to_update (GDScriptFunction **p_func_ptr_ptr) {
1398- MutexLock lock (func_ptrs_to_update_mutex);
1399-
1400- List<UpdatableFuncPtrElement>::Element *result = func_ptrs_to_update_elems.push_back (UpdatableFuncPtrElement ());
1396+ GDScript::UpdatableFuncPtrElement GDScript::_add_func_ptr_to_update (GDScriptFunction **p_func_ptr_ptr) {
1397+ UpdatableFuncPtrElement result = {};
14011398
14021399 {
1403- MutexLock lock2 (func_ptrs_to_update_thread_local.mutex );
1404- result-> get () .element = func_ptrs_to_update_thread_local.ptrs .push_back (p_func_ptr_ptr);
1405- result-> get () .mutex = &func_ptrs_to_update_thread_local.mutex ;
1400+ MutexLock lock (func_ptrs_to_update_thread_local.mutex );
1401+ result.element = func_ptrs_to_update_thread_local.ptrs .push_back (p_func_ptr_ptr);
1402+ result.mutex = &func_ptrs_to_update_thread_local.mutex ;
14061403
14071404 if (likely (func_ptrs_to_update_thread_local.initialized )) {
14081405 return result;
@@ -1411,89 +1408,17 @@ List<GDScript::UpdatableFuncPtrElement>::Element *GDScript::_add_func_ptr_to_upd
14111408 func_ptrs_to_update_thread_local.initialized = true ;
14121409 }
14131410
1411+ MutexLock lock (func_ptrs_to_update_mutex);
14141412 func_ptrs_to_update.push_back (&func_ptrs_to_update_thread_local);
14151413
14161414 return result;
14171415}
14181416
1419- void GDScript::_remove_func_ptr_to_update (List<UpdatableFuncPtrElement>::Element *p_func_ptr_element) {
1420- // None of these checks should ever fail, unless there's a bug.
1421- // They can be removed once we are sure they never catch anything.
1422- // Left here now due to extra safety needs late in the release cycle.
1423- ERR_FAIL_NULL (p_func_ptr_element);
1424- MutexLock lock (func_ptrs_to_update_thread_local.mutex );
1425- ERR_FAIL_NULL (p_func_ptr_element->get ().element );
1426- ERR_FAIL_NULL (p_func_ptr_element->get ().mutex );
1427- MutexLock lock2 (*p_func_ptr_element->get ().mutex );
1428- p_func_ptr_element->get ().element ->erase ();
1429- p_func_ptr_element->erase ();
1430- }
1431-
1432- void GDScript::_fixup_thread_function_bookkeeping () {
1433- // Transfer the ownership of these update items to the main thread,
1434- // because the current one is dying, leaving theirs orphan, dangling.
1435-
1436- HashSet<GDScript *> scripts;
1437-
1438- DEV_ASSERT (!Thread::is_main_thread ());
1439- MutexLock lock (func_ptrs_to_update_main_thread->mutex );
1440-
1441- {
1442- MutexLock lock2 (func_ptrs_to_update_thread_local.mutex );
1443-
1444- while (!func_ptrs_to_update_thread_local.ptrs .is_empty ()) {
1445- // Transfer the thread-to-script records from the dying thread to the main one.
1446-
1447- List<GDScriptFunction **>::Element *E = func_ptrs_to_update_thread_local.ptrs .front ();
1448- List<GDScriptFunction **>::Element *new_E = func_ptrs_to_update_main_thread->ptrs .push_front (E->get ());
1449-
1450- GDScript *script = (*E->get ())->get_script ();
1451- if (!scripts.has (script)) {
1452- scripts.insert (script);
1453-
1454- // Replace dying thread by the main thread in the script-to-thread records.
1455-
1456- MutexLock lock3 (script->func_ptrs_to_update_mutex );
1457- DEV_ASSERT (script->func_ptrs_to_update .find (&func_ptrs_to_update_thread_local));
1458- {
1459- for (List<UpdatableFuncPtrElement>::Element *F = script->func_ptrs_to_update_elems .front (); F; F = F->next ()) {
1460- bool is_dying_thread_entry = F->get ().mutex == &func_ptrs_to_update_thread_local.mutex ;
1461- if (is_dying_thread_entry) {
1462- // This may lead to multiple main-thread entries, but that's not a problem
1463- // and allows to reuse the element, which is needed, since it's tracked by pointer.
1464- F->get ().element = new_E;
1465- F->get ().mutex = &func_ptrs_to_update_main_thread->mutex ;
1466- }
1467- }
1468- }
1469- }
1470-
1471- E->erase ();
1472- }
1473- }
1474- func_ptrs_to_update_main_thread->initialized = true ;
1475-
1476- {
1477- // Remove orphan thread-to-script entries from every script.
1478- // FIXME: This involves iterating through every script whenever a thread dies.
1479- // While it's OK that thread creation/destruction are heavy operations,
1480- // additional bookkeeping can be used to outperform this brute-force approach.
1481-
1482- GDScriptLanguage *gd_lang = GDScriptLanguage::get_singleton ();
1483-
1484- MutexLock lock2 (gd_lang->mutex );
1485-
1486- for (SelfList<GDScript> *s = gd_lang->script_list .first (); s; s = s->next ()) {
1487- GDScript *script = s->self ();
1488- for (List<UpdatableFuncPtr *>::Element *E = script->func_ptrs_to_update .front (); E; E = E->next ()) {
1489- bool is_dying_thread_entry = &E->get ()->mutex == &func_ptrs_to_update_thread_local.mutex ;
1490- if (is_dying_thread_entry) {
1491- E->erase ();
1492- break ;
1493- }
1494- }
1495- }
1496- }
1417+ void GDScript::_remove_func_ptr_to_update (const UpdatableFuncPtrElement p_func_ptr_element) {
1418+ ERR_FAIL_NULL (p_func_ptr_element.element );
1419+ ERR_FAIL_NULL (p_func_ptr_element.mutex );
1420+ MutexLock lock (*p_func_ptr_element.mutex );
1421+ p_func_ptr_element.element ->erase ();
14971422}
14981423
14991424void GDScript::clear (ClearData *p_clear_data) {
@@ -1521,7 +1446,6 @@ void GDScript::clear(ClearData *p_clear_data) {
15211446 *func_ptr_ptr = nullptr ;
15221447 }
15231448 }
1524- func_ptrs_to_update_elems.clear ();
15251449 }
15261450
15271451 RBSet<GDScript *> must_clear_dependencies = get_must_clear_dependencies ();
@@ -2141,10 +2065,6 @@ void GDScriptLanguage::remove_named_global_constant(const StringName &p_name) {
21412065 named_globals.erase (p_name);
21422066}
21432067
2144- void GDScriptLanguage::thread_exit () {
2145- GDScript::_fixup_thread_function_bookkeeping ();
2146- }
2147-
21482068void GDScriptLanguage::init () {
21492069 // populate global constants
21502070 int gcc = CoreConstants::get_global_constant_count ();
0 commit comments