Mono/C#: Lighten up unsafe reference checks
Because of the weird case with multi-threading and ResourceLoader, it can be the case that a resource is GCed while being referenced again in the main thread. In such cases, a new unsafe reference is created before the finalizer thread removes the previous one.
This commit is contained in:
parent
1c0995d450
commit
55b2e58a98
2 changed files with 25 additions and 7 deletions
|
@ -160,7 +160,7 @@ void CSharpLanguage::finish() {
|
||||||
script_bindings.clear();
|
script_bindings.clear();
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
for (List<ObjectID>::Element *E = unsafely_referenced_objects.front(); E; E = E->next()) {
|
for (Map<ObjectID, int>::Element *E = unsafe_object_references.front(); E; E = E->next()) {
|
||||||
const ObjectID &id = E->get();
|
const ObjectID &id = E->get();
|
||||||
Object *obj = ObjectDB::get_instance(id);
|
Object *obj = ObjectDB::get_instance(id);
|
||||||
|
|
||||||
|
@ -632,18 +632,20 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
|
||||||
|
|
||||||
void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
|
void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
|
||||||
ObjectID id = p_obj->get_instance_id();
|
ObjectID id = p_obj->get_instance_id();
|
||||||
ERR_FAIL_COND_MSG(unsafely_referenced_objects.find(id), "Multiple unsafe references for object: " + p_obj->get_class() + ":" + itos(id));
|
unsafe_object_references[id]++;
|
||||||
unsafely_referenced_objects.push_back(id);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
|
void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
|
||||||
ObjectID id = p_obj->get_instance_id();
|
ObjectID id = p_obj->get_instance_id();
|
||||||
List<ObjectID>::Element *elem = unsafely_referenced_objects.find(id);
|
Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id);
|
||||||
ERR_FAIL_NULL(elem);
|
ERR_FAIL_NULL(elem);
|
||||||
unsafely_referenced_objects.erase(elem);
|
if (--elem->value() == 0)
|
||||||
|
unsafe_object_references.erase(elem);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,6 +1248,14 @@ CSharpLanguage::CSharpLanguage() {
|
||||||
language_bind_mutex = Mutex::create();
|
language_bind_mutex = Mutex::create();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
#ifdef NO_THREADS
|
||||||
|
unsafe_object_references_lock = NULL;
|
||||||
|
#else
|
||||||
|
unsafe_object_references_lock = Mutex::create();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
lang_idx = -1;
|
lang_idx = -1;
|
||||||
|
|
||||||
scripts_metadata_invalidated = true;
|
scripts_metadata_invalidated = true;
|
||||||
|
@ -1274,6 +1284,13 @@ CSharpLanguage::~CSharpLanguage() {
|
||||||
script_gchandle_release_mutex = NULL;
|
script_gchandle_release_mutex = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (unsafe_object_references_lock) {
|
||||||
|
memdelete(unsafe_object_references_lock);
|
||||||
|
unsafe_object_references_lock = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
singleton = NULL;
|
singleton = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -308,8 +308,9 @@ class CSharpLanguage : public ScriptLanguage {
|
||||||
Map<Object *, CSharpScriptBinding> script_bindings;
|
Map<Object *, CSharpScriptBinding> script_bindings;
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
// List of unsafely referenced objects
|
// List of unsafe object references
|
||||||
List<ObjectID> unsafely_referenced_objects;
|
Map<ObjectID, int> unsafe_object_references;
|
||||||
|
Mutex *unsafe_object_references_lock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct StringNameCache {
|
struct StringNameCache {
|
||||||
|
|
Loading…
Reference in a new issue