Avoid reentrant OBJTYPE_RLOCK in ClassDB
Fixes #43020 when a thread uses ClassDB while main thread calls is_parent_class().
This commit is contained in:
parent
a392aa455f
commit
d3be8477f0
@ -270,9 +270,7 @@ ClassDB::ClassInfo::ClassInfo() {
|
|||||||
ClassDB::ClassInfo::~ClassInfo() {
|
ClassDB::ClassInfo::~ClassInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) {
|
bool ClassDB::_is_parent_class(const StringName &p_class, const StringName &p_inherits) {
|
||||||
|
|
||||||
OBJTYPE_RLOCK;
|
|
||||||
|
|
||||||
StringName inherits = p_class;
|
StringName inherits = p_class;
|
||||||
|
|
||||||
@ -280,11 +278,19 @@ bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inh
|
|||||||
|
|
||||||
if (inherits == p_inherits)
|
if (inherits == p_inherits)
|
||||||
return true;
|
return true;
|
||||||
inherits = get_parent_class(inherits);
|
inherits = _get_parent_class(inherits);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) {
|
||||||
|
|
||||||
|
OBJTYPE_RLOCK;
|
||||||
|
|
||||||
|
return _is_parent_class(p_class, p_inherits);
|
||||||
|
}
|
||||||
|
|
||||||
void ClassDB::get_class_list(List<StringName> *p_classes) {
|
void ClassDB::get_class_list(List<StringName> *p_classes) {
|
||||||
|
|
||||||
OBJTYPE_RLOCK;
|
OBJTYPE_RLOCK;
|
||||||
@ -307,7 +313,7 @@ void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringNa
|
|||||||
|
|
||||||
while ((k = classes.next(k))) {
|
while ((k = classes.next(k))) {
|
||||||
|
|
||||||
if (*k != p_class && is_parent_class(*k, p_class))
|
if (*k != p_class && _is_parent_class(*k, p_class))
|
||||||
p_classes->push_back(*k);
|
p_classes->push_back(*k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,7 +326,7 @@ void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List<S
|
|||||||
|
|
||||||
while ((k = classes.next(k))) {
|
while ((k = classes.next(k))) {
|
||||||
|
|
||||||
if (*k != p_class && get_parent_class(*k) == p_class)
|
if (*k != p_class && _get_parent_class(*k) == p_class)
|
||||||
p_classes->push_back(*k);
|
p_classes->push_back(*k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,15 +341,20 @@ StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) {
|
|||||||
return ti->inherits;
|
return ti->inherits;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName ClassDB::get_parent_class(const StringName &p_class) {
|
StringName ClassDB::_get_parent_class(const StringName &p_class) {
|
||||||
|
|
||||||
OBJTYPE_RLOCK;
|
|
||||||
|
|
||||||
ClassInfo *ti = classes.getptr(p_class);
|
ClassInfo *ti = classes.getptr(p_class);
|
||||||
ERR_FAIL_COND_V_MSG(!ti, StringName(), "Cannot get class '" + String(p_class) + "'.");
|
ERR_FAIL_COND_V_MSG(!ti, StringName(), "Cannot get class '" + String(p_class) + "'.");
|
||||||
return ti->inherits;
|
return ti->inherits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringName ClassDB::get_parent_class(const StringName &p_class) {
|
||||||
|
|
||||||
|
OBJTYPE_RLOCK;
|
||||||
|
|
||||||
|
return _get_parent_class(p_class);
|
||||||
|
}
|
||||||
|
|
||||||
ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) {
|
ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) {
|
||||||
|
|
||||||
OBJTYPE_RLOCK;
|
OBJTYPE_RLOCK;
|
||||||
|
@ -161,6 +161,11 @@ public:
|
|||||||
static HashMap<StringName, HashMap<StringName, Variant> > default_values;
|
static HashMap<StringName, HashMap<StringName, Variant> > default_values;
|
||||||
static Set<StringName> default_values_cached;
|
static Set<StringName> default_values_cached;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Non-locking variants of get_parent_class and is_parent_class.
|
||||||
|
static StringName _get_parent_class(const StringName &p_class);
|
||||||
|
static bool _is_parent_class(const StringName &p_class, const StringName &p_inherits);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
|
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
|
||||||
template <class T>
|
template <class T>
|
||||||
|
Loading…
Reference in New Issue
Block a user