From 1efdad47e7b3109c3531c2c0d8ce441e56f1ac8e Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 11 Jun 2025 14:57:34 +0530 Subject: [PATCH 1/2] enhance critical section held assertions --- Include/internal/pycore_critical_section.h | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Include/internal/pycore_critical_section.h b/Include/internal/pycore_critical_section.h index 42f06b935bd0a0..93f93bb3762ed4 100644 --- a/Include/internal/pycore_critical_section.h +++ b/Include/internal/pycore_critical_section.h @@ -64,7 +64,7 @@ extern "C" { # define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op) \ if (Py_REFCNT(op) != 1) { \ - _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&_PyObject_CAST(op)->ob_mutex); \ + _PyCriticalSection_AssertHeldObj((PyObject *) op); \ } #else /* Py_DEBUG */ @@ -239,6 +239,28 @@ _PyCriticalSection_AssertHeld(PyMutex *mutex) #endif } +static inline void +_PyCriticalSection_AssertHeldObj(PyObject *op) +{ +#ifdef Py_DEBUG + PyMutex *mutex = &_PyObject_CAST(op)->ob_mutex; + PyThreadState *tstate = _PyThreadState_GET(); + uintptr_t prev = tstate->critical_section; + if (prev & _Py_CRITICAL_SECTION_TWO_MUTEXES) { + PyCriticalSection2 *cs = (PyCriticalSection2 *)(prev & ~_Py_CRITICAL_SECTION_MASK); + _PyObject_ASSERT_WITH_MSG(op, + (cs != NULL && (cs->_cs_base._cs_mutex == mutex || cs->_cs_mutex2 == mutex)), + "Critical section of object is not held"); + } + else { + PyCriticalSection *cs = (PyCriticalSection *)(tstate->critical_section & ~_Py_CRITICAL_SECTION_MASK); + _PyObject_ASSERT_WITH_MSG(op, + (cs != NULL && cs->_cs_mutex == mutex), + "Critical section of object is not held"); + } + +#endif +} #endif /* Py_GIL_DISABLED */ #ifdef __cplusplus From 3620385380677809ff9aadaa2ac5fec2a9132754 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Thu, 12 Jun 2025 13:52:51 +0530 Subject: [PATCH 2/2] code review --- Include/internal/pycore_critical_section.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_critical_section.h b/Include/internal/pycore_critical_section.h index 93f93bb3762ed4..62460c5f8fad30 100644 --- a/Include/internal/pycore_critical_section.h +++ b/Include/internal/pycore_critical_section.h @@ -64,7 +64,7 @@ extern "C" { # define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op) \ if (Py_REFCNT(op) != 1) { \ - _PyCriticalSection_AssertHeldObj((PyObject *) op); \ + _PyCriticalSection_AssertHeldObj(_PyObject_CAST(op)); \ } #else /* Py_DEBUG */ @@ -253,7 +253,7 @@ _PyCriticalSection_AssertHeldObj(PyObject *op) "Critical section of object is not held"); } else { - PyCriticalSection *cs = (PyCriticalSection *)(tstate->critical_section & ~_Py_CRITICAL_SECTION_MASK); + PyCriticalSection *cs = (PyCriticalSection *)(prev & ~_Py_CRITICAL_SECTION_MASK); _PyObject_ASSERT_WITH_MSG(op, (cs != NULL && cs->_cs_mutex == mutex), "Critical section of object is not held");