@@ -104,12 +104,29 @@ extern "C" {
104
104
# define Py_END_CRITICAL_SECTION2 () \
105
105
_PyCriticalSection2_End(&_cs2); \
106
106
}
107
+
108
+ // Asserts that the mutex is locked. The mutex must be held by the
109
+ // top-most critical section otherwise there's the possibility
110
+ // that the mutex would be swalled out in some code paths.
111
+ #define _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED (mutex ) \
112
+ _PyCriticalSection_AssertHeld(mutex)
113
+
114
+ // Asserts that the mutex for the given object is locked. The mutex must
115
+ // be held by the top-most critical section otherwise there's the
116
+ // possibility that the mutex would be swalled out in some code paths.
117
+ #define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (op ) \
118
+ _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&_PyObject_CAST(op)->ob_mutex)
119
+
120
+
121
+
107
122
#else /* !Py_GIL_DISABLED */
108
123
// The critical section APIs are no-ops with the GIL.
109
124
# define Py_BEGIN_CRITICAL_SECTION (op )
110
125
# define Py_END_CRITICAL_SECTION ()
111
126
# define Py_BEGIN_CRITICAL_SECTION2 (a , b )
112
127
# define Py_END_CRITICAL_SECTION2 ()
128
+ # define _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED (mutex )
129
+ # define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (op )
113
130
#endif /* !Py_GIL_DISABLED */
114
131
115
132
typedef struct {
@@ -236,6 +253,19 @@ _PyCriticalSection2_End(_PyCriticalSection2 *c)
236
253
PyAPI_FUNC (void )
237
254
_PyCriticalSection_SuspendAll (PyThreadState * tstate );
238
255
256
+ #ifdef Py_GIL_DISABLED
257
+
258
+ static inline void
259
+ _PyCriticalSection_AssertHeld (PyMutex * mutex ) {
260
+ #ifdef Py_DEBUG
261
+ PyThreadState * tstate = _PyThreadState_GET ();
262
+ _PyCriticalSection * cs = (_PyCriticalSection * )tstate -> critical_section ;
263
+ assert (cs != NULL && cs -> mutex == mutex );
264
+ #endif
265
+ }
266
+
267
+ #endif
268
+
239
269
#ifdef __cplusplus
240
270
}
241
271
#endif
0 commit comments