Skip to content

Commit 018d0e8

Browse files
committed
Make bases/mro accesses thread safe
1 parent 574d637 commit 018d0e8

File tree

4 files changed

+276
-65
lines changed

4 files changed

+276
-65
lines changed

Include/internal/pycore_typeobject.h

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern "C" {
99
#endif
1010

1111
#include "pycore_moduleobject.h" // PyModuleObject
12+
#include "pycore_lock.h" // PyMutex
1213

1314

1415
/* state */
@@ -21,6 +22,7 @@ struct _types_runtime_state {
2122
// bpo-42745: next_version_tag remains shared by all interpreters
2223
// because of static types.
2324
unsigned int next_version_tag;
25+
PyMutex type_mutex;
2426
};
2527

2628

Modules/_abc.c

+4-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include "pycore_object.h" // _PyType_GetSubclasses()
99
#include "pycore_runtime.h" // _Py_ID()
1010
#include "pycore_setobject.h" // _PySet_NextEntry()
11-
#include "pycore_typeobject.h" // _PyType_GetMRO()
1211
#include "pycore_weakref.h" // _PyWeakref_GET_REF()
1312
#include "clinic/_abc.c.h"
1413

@@ -744,18 +743,12 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
744743
Py_DECREF(ok);
745744

746745
/* 4. Check if it's a direct subclass. */
747-
PyObject *mro = _PyType_GetMRO((PyTypeObject *)subclass);
748-
assert(PyTuple_Check(mro));
749-
for (pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) {
750-
PyObject *mro_item = PyTuple_GET_ITEM(mro, pos);
751-
assert(mro_item != NULL);
752-
if ((PyObject *)self == mro_item) {
753-
if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
754-
goto end;
755-
}
756-
result = Py_True;
746+
if (PyType_IsSubtype((PyTypeObject *)subclass, (PyTypeObject *)self)) {
747+
if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
757748
goto end;
758749
}
750+
result = Py_True;
751+
goto end;
759752
}
760753

761754
/* 5. Check if it's a subclass of a registered class (recursive). */

0 commit comments

Comments
 (0)