diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2020-09-26 23:20:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-26 23:20:31 +0200 |
commit | bfd5b58223e91598b62cecf5ec0d92bd4c6f7154 (patch) | |
tree | 2a9f4153bbe6de81c0603532b0212135e339ec28 | |
parent | 84cec777c14f5d6bc3fbed425906211044429380 (diff) | |
parent | de4e54dd9150b0bc8bcb2ec643dd40eb4d3598d0 (diff) |
Merge pull request #42356 from RandomShaper/fix_gdscript_inf_loop
Avoid infinite loop in GDScript at shutdown
-rw-r--r-- | modules/gdscript/gdscript.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 7f303a966d..3519038ae6 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2039,8 +2039,15 @@ GDScriptLanguage::~GDScriptLanguage() { } // Clear dependencies between scripts, to ensure cyclic references are broken (to avoid leaks at exit). - while (script_list.first()) { - GDScript *script = script_list.first()->self(); + SelfList<GDScript> *s = script_list.first(); + while (s) { + GDScript *script = s->self(); + // This ensures the current script is not released before we can check what's the next one + // in the list (we can't get the next upfront because we don't know if the reference breaking + // will cause it -or any other after it, for that matter- to be released so the next one + // is not the same as before). + script->reference(); + for (Map<StringName, GDScriptFunction *>::Element *E = script->member_functions.front(); E; E = E->next()) { GDScriptFunction *func = E->get(); for (int i = 0; i < func->argument_types.size(); i++) { @@ -2051,6 +2058,9 @@ GDScriptLanguage::~GDScriptLanguage() { for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) { E->get().data_type.script_type_ref = Ref<Script>(); } + + s = s->next(); + script->unreference(); } singleton = NULL; |