Selaa lähdekoodia

Merge pull request #26842 from karroffel/gdnative-singleton-crash

[GDNative] fix crash at shutdown when using singleton libraries and NativeScript
Rémi Verschelde 6 vuotta sitten
vanhempi
commit
d41cd57595
2 muutettua tiedostoa jossa 26 lisäystä ja 2 poistoa
  1. 1 0
      modules/gdnative/gdnative.cpp
  2. 25 2
      modules/gdnative/nativescript/nativescript.cpp

+ 1 - 0
modules/gdnative/gdnative.cpp

@@ -414,6 +414,7 @@ bool GDNative::terminate() {
 	if (error || !library_terminate) {
 		OS::get_singleton()->close_dynamic_library(native_handle);
 		native_handle = NULL;
+		initialized = false;
 		return true;
 	}
 

+ 25 - 2
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;