summaryrefslogtreecommitdiffstats
path: root/modules/gdnative/nativescript/nativescript.cpp
diff options
context:
space:
mode:
authorkarroffel <therzog@mail.de>2019-03-09 18:01:08 +0100
committerkarroffel <therzog@mail.de>2019-03-09 18:01:08 +0100
commit9786b5160140f7b2462db6a18bf4a7a524fbb6d9 (patch)
treee2a5f8308ba0bc5439d946f967e016005c3c53a9 /modules/gdnative/nativescript/nativescript.cpp
parent362b42787b8c48da61b3cb7cd2de718d259d723f (diff)
downloadredot-engine-9786b5160140f7b2462db6a18bf4a7a524fbb6d9.tar.gz
[GDNative] fix crash at shutdown when using singleton libraries and NativeScript
When a singleton library was exposing NativeScript functionality, the NativeScriptLanguage would attempt to terminate the library at shutdown. Since the GDNative module itself handles singleton libraries, it closes all singleton libraries at shutdown as well. This double free could cause a crash, since the library referenced would no longer be alive.
Diffstat (limited to 'modules/gdnative/nativescript/nativescript.cpp')
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index c2b772df85..2da9d6bfdc 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -1036,8 +1036,16 @@ NativeScriptLanguage::~NativeScriptLanguage() {
for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
- if (L->get().is_valid())
- L->get()->terminate();
+ Ref<GDNative> lib = L->get();
+ // only shut down valid libs, duh!
+ if (lib.is_valid()) {
+
+ // If it's a singleton-library then the gdnative module
+ // manages the destruction at engine shutdown, not NativeScript.
+ if (!lib->get_library()->is_singleton()) {
+ lib->terminate();
+ }
+ }
}
NSL->library_classes.clear();
@@ -1641,10 +1649,19 @@ void NativeReloadNode::_notification(int p_what) {
continue;
}
+ // Don't unload what should not be reloaded!
if (!gdn->get_library()->is_reloadable()) {
continue;
}
+ // singleton libraries might have alive pointers living inside the
+ // editor. Also reloading a singleton library would mean that
+ // the singleton entry will not be called again, as this only
+ // happens at engine startup.
+ if (gdn->get_library()->is_singleton()) {
+ continue;
+ }
+
gdn->terminate();
}
@@ -1672,6 +1689,12 @@ void NativeReloadNode::_notification(int p_what) {
continue;
}
+ // since singleton libraries are not unloaded there is no point
+ // in loading them again.
+ if (!gdn->get_library()->is_singleton()) {
+ continue;
+ }
+
if (!gdn->initialize()) {
libs_to_remove.insert(L->key());
continue;