Browse Source

Merge pull request #12549 from neikeq/seriously-do-they

Mono cleanup fixes
Ignacio Etcheverry 7 years ago
parent
commit
3c97a9543d

+ 11 - 0
modules/mono/csharp_script.cpp

@@ -122,6 +122,9 @@ void CSharpLanguage::init() {
 
 
 void CSharpLanguage::finish() {
 void CSharpLanguage::finish() {
 
 
+	// Release gchandle bindings before finalizing mono runtime
+	gchandle_bindings.clear();
+
 	if (gdmono) {
 	if (gdmono) {
 		memdelete(gdmono);
 		memdelete(gdmono);
 		gdmono = NULL;
 		gdmono = NULL;
@@ -827,6 +830,14 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
 
 
 void CSharpLanguage::free_instance_binding_data(void *p_data) {
 void CSharpLanguage::free_instance_binding_data(void *p_data) {
 
 
+	if (GDMono::get_singleton() == NULL) {
+#ifdef DEBUG_ENABLED
+		CRASH_COND(!gchandle_bindings.empty());
+#endif
+		// Mono runtime finalized, all the gchandle bindings were already released
+		return;
+	}
+
 #ifndef NO_THREADS
 #ifndef NO_THREADS
 	script_bind_lock->lock();
 	script_bind_lock->lock();
 #endif
 #endif

+ 4 - 0
modules/mono/mono_gc_handle.cpp

@@ -59,6 +59,10 @@ Ref<MonoGCHandle> MonoGCHandle::create_weak(MonoObject *p_object) {
 
 
 void MonoGCHandle::release() {
 void MonoGCHandle::release() {
 
 
+#ifdef DEBUG_ENABLED
+	CRASH_COND(GDMono::get_singleton() == NULL);
+#endif
+
 	if (!released && GDMono::get_singleton()->is_runtime_initialized()) {
 	if (!released && GDMono::get_singleton()->is_runtime_initialized()) {
 		mono_gchandle_free(handle);
 		mono_gchandle_free(handle);
 		released = true;
 		released = true;

+ 3 - 3
modules/mono/mono_gd/gd_mono.cpp

@@ -705,7 +705,7 @@ bool _GodotSharp::is_domain_loaded() {
 
 
 void _GodotSharp::queue_dispose(Object *p_object) {
 void _GodotSharp::queue_dispose(Object *p_object) {
 
 
-	if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
+	if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
 		_dispose_object(p_object);
 		_dispose_object(p_object);
 	} else {
 	} else {
 #ifndef NO_THREADS
 #ifndef NO_THREADS
@@ -722,7 +722,7 @@ void _GodotSharp::queue_dispose(Object *p_object) {
 
 
 void _GodotSharp::queue_dispose(NodePath *p_node_path) {
 void _GodotSharp::queue_dispose(NodePath *p_node_path) {
 
 
-	if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
+	if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
 		memdelete(p_node_path);
 		memdelete(p_node_path);
 	} else {
 	} else {
 #ifndef NO_THREADS
 #ifndef NO_THREADS
@@ -739,7 +739,7 @@ void _GodotSharp::queue_dispose(NodePath *p_node_path) {
 
 
 void _GodotSharp::queue_dispose(RID *p_rid) {
 void _GodotSharp::queue_dispose(RID *p_rid) {
 
 
-	if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
+	if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
 		memdelete(p_rid);
 		memdelete(p_rid);
 	} else {
 	} else {
 #ifndef NO_THREADS
 #ifndef NO_THREADS

+ 4 - 0
modules/mono/mono_gd/gd_mono_utils.h

@@ -149,6 +149,10 @@ void attach_current_thread();
 void detach_current_thread();
 void detach_current_thread();
 MonoThread *get_current_thread();
 MonoThread *get_current_thread();
 
 
+_FORCE_INLINE_ bool is_main_thread() {
+	return mono_domain_get() != NULL && mono_thread_get_main() == mono_thread_current();
+}
+
 GDMonoClass *get_object_class(MonoObject *p_object);
 GDMonoClass *get_object_class(MonoObject *p_object);
 GDMonoClass *type_get_proxy_class(const StringName &p_type);
 GDMonoClass *type_get_proxy_class(const StringName &p_type);
 GDMonoClass *get_class_native_base(GDMonoClass *p_class);
 GDMonoClass *get_class_native_base(GDMonoClass *p_class);