-
-
Notifications
You must be signed in to change notification settings - Fork 21.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move GDScript uninitialization to GDScriptLanguage::finish()
#69506
Move GDScript uninitialization to GDScriptLanguage::finish()
#69506
Conversation
9776b7c
to
a5dec4d
Compare
Credited @rburing as a co-author for his valuable help. |
a5dec4d
to
65c3cd0
Compare
65c3cd0
to
b615f7f
Compare
@unfa This PR should fix the crash that happens when closing Liblast. |
modules/gdscript/gdscript.cpp
Outdated
if (finalizing) { | ||
return; | ||
} | ||
finalizing = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would now work, but I'm a bit confused because now finalize()
will be called both by GDScriptLanguage::finish()
and GDScriptLanguage::~GDScriptLanguage()
, but it will only do something for the first one that calls it.
Is that order non deterministic, or why do we need to call it in both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm. Yeah, calling it once should work. I'll let the finalizing
variable there, just to be sure that it's not called twice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess there's no need for a new finalize()
method now and it can go in finish()
directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I was inspired by csharp_script.cpp
, which explains a lot, but yes, I'll transfer everything into finish()
.
godot/modules/mono/csharp_script.cpp
Lines 128 to 140 in bcc061e
void CSharpLanguage::finish() { | |
finalize(); | |
} | |
void CSharpLanguage::finalize() { | |
if (finalized) { | |
return; | |
} | |
finalizing = true; | |
// Make sure all script binding gchandles are released before finalizing GDMono | |
for (KeyValue<Object *, CSharpScriptBinding> &E : script_bindings) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe @neikeq can give some input then, there might be a good reason to still call finalize()
in both finish()
and the destructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe @neikeq can give some input then, there might be a good reason to still call
finalize()
in bothfinish()
and the destructor.
I don't really remember, to be honest, and I'm afraid changing it could cause an issue. I wish I had left an explanatory comment there...
The reason it's a different method (finalize
) is because clang-tidy warns when calling virtual methods (finish
) from the destructor.
4504117
to
a7ce34c
Compare
27d2163
to
480fcae
Compare
@kleonc I added you as co-author of the PR. |
Barely did anything but sure, fine for me. Gotta be able to blame someone for these changes. 😄 |
GDScriptLanguage::finalize()
GDScriptLanguage::finish()
b136167
to
46f4f94
Compare
Co-authored-by: Ricardo Buring <ricardo.buring@gmail.com> Co-authored-by: kleonc <9283098+kleonc@users.noreply.github.com>
46f4f94
to
88f3045
Compare
Thanks! |
@akien-mga Thanks for the review! 😊 |
GDScriptLanguage::finish()
was empty. So I moved the uninitialization of GDScriptLanguage originally inGDScriptLanguage::~GDScriptLanguage()
inside it, calling too a newGDScriptCache::clear()
to clear the cache sooner than the destructor. Andfinish_languages
is called before the servers uninit.As cyclic references didn't exist, there wasn't any GDScript instance that could live after the removal of the root script, so it wasn't a problem until cyclic references (which could make it so that instances could live beyond the root script).
The problem existed when
cycliccached scripts would hold RID past the uninitialization of the servers.Fixes #68973
Would be interesting to merge with #69077