mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
[3.14] gh-123241: Don't modify ref count during visitation (GH-142232) (#142567)
(cherry picked from commit da8199f884)
Co-authored-by: Dino Viehland <dinoviehland@meta.com>
This commit is contained in:
parent
65d07f1948
commit
e09c4deb25
4 changed files with 41 additions and 22 deletions
|
|
@ -149,6 +149,11 @@ typedef int (*_py_validate_type)(PyTypeObject *);
|
|||
extern int _PyType_Validate(PyTypeObject *ty, _py_validate_type validate, unsigned int *tp_version);
|
||||
extern int _PyType_CacheGetItemForSpecialization(PyHeapTypeObject *ht, PyObject *descriptor, uint32_t tp_version);
|
||||
|
||||
// Like PyType_GetBaseByToken, but does not modify refcounts.
|
||||
// Cannot fail; arguments must be valid.
|
||||
PyAPI_FUNC(int)
|
||||
_PyType_GetBaseByToken_Borrow(PyTypeObject *type, void *token, PyTypeObject **result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Avoid reference count operations in garbage collection of :mod:`ctypes`
|
||||
objects.
|
||||
|
|
@ -596,7 +596,8 @@ PyStgInfo_FromAny(ctypes_state *state, PyObject *obj, StgInfo **result)
|
|||
return _stginfo_from_type(state, Py_TYPE(obj), result);
|
||||
}
|
||||
|
||||
/* A variant of PyStgInfo_FromType that doesn't need the state,
|
||||
/* A variant of PyStgInfo_FromType that doesn't need the state
|
||||
* and doesn't modify any refcounts,
|
||||
* so it can be called from finalization functions when the module
|
||||
* state is torn down.
|
||||
*/
|
||||
|
|
@ -604,17 +605,12 @@ static inline StgInfo *
|
|||
_PyStgInfo_FromType_NoState(PyObject *type)
|
||||
{
|
||||
PyTypeObject *PyCType_Type;
|
||||
if (PyType_GetBaseByToken(Py_TYPE(type), &pyctype_type_spec, &PyCType_Type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyCType_Type == NULL) {
|
||||
PyErr_Format(PyExc_TypeError, "expected a ctypes type, got '%N'", type);
|
||||
if (_PyType_GetBaseByToken_Borrow(Py_TYPE(type), &pyctype_type_spec, &PyCType_Type) < 0 ||
|
||||
PyCType_Type == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StgInfo *info = PyObject_GetTypeData(type, PyCType_Type);
|
||||
Py_DECREF(PyCType_Type);
|
||||
return info;
|
||||
return PyObject_GetTypeData(type, PyCType_Type);
|
||||
}
|
||||
|
||||
// Initialize StgInfo on a newly created type
|
||||
|
|
|
|||
|
|
@ -5533,23 +5533,15 @@ get_base_by_token_recursive(PyObject *bases, void *token)
|
|||
}
|
||||
|
||||
int
|
||||
PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result)
|
||||
_PyType_GetBaseByToken_Borrow(PyTypeObject *type, void *token, PyTypeObject **result)
|
||||
{
|
||||
assert(token != NULL);
|
||||
assert(PyType_Check(type));
|
||||
|
||||
if (result != NULL) {
|
||||
*result = NULL;
|
||||
}
|
||||
|
||||
if (token == NULL) {
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"PyType_GetBaseByToken called with token=NULL");
|
||||
return -1;
|
||||
}
|
||||
if (!PyType_Check(type)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"expected a type, got a '%T' object", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
|
||||
// No static type has a heaptype superclass,
|
||||
// which is ensured by type_ready_mro().
|
||||
|
|
@ -5558,7 +5550,7 @@ PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result)
|
|||
if (((PyHeapTypeObject*)type)->ht_token == token) {
|
||||
found:
|
||||
if (result != NULL) {
|
||||
*result = (PyTypeObject *)Py_NewRef(type);
|
||||
*result = type;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -5592,6 +5584,30 @@ PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result)
|
||||
{
|
||||
if (result != NULL) {
|
||||
*result = NULL;
|
||||
}
|
||||
if (token == NULL) {
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"PyType_GetBaseByToken called with token=NULL");
|
||||
return -1;
|
||||
}
|
||||
if (!PyType_Check(type)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"expected a type, got a '%T' object", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int res = _PyType_GetBaseByToken_Borrow(type, token, result);
|
||||
if (res > 0 && result) {
|
||||
Py_INCREF(*result);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
PyObject_GetTypeData(PyObject *obj, PyTypeObject *cls)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue