@@ -103,14 +103,25 @@ _PyManagedBuffer_FromObject(PyObject *base, int flags)
103103 return (PyObject * )mbuf ;
104104}
105105
106+ static inline int
107+ atomic_or (int * flags , int bit )
108+ {
109+ #ifdef Py_GIL_DISABLED
110+ return (int )_Py_atomic_or_uint32 ((uint32_t * )flags , (uint32_t )bit );
111+ #else
112+ int prev = * flags ;
113+ * flags = prev | bit ;
114+ return prev ;
115+ #endif
116+ }
117+
106118static void
107119mbuf_release (_PyManagedBufferObject * self )
108120{
109- if (self -> flags & _Py_MANAGED_BUFFER_RELEASED )
121+ int prev_flags = atomic_or (& self -> flags , _Py_MANAGED_BUFFER_RELEASED );
122+ if (prev_flags & _Py_MANAGED_BUFFER_RELEASED )
110123 return ;
111124
112- self -> flags |= _Py_MANAGED_BUFFER_RELEASED ;
113-
114125 /* PyBuffer_Release() decrements master->obj and sets it to NULL. */
115126 _PyObject_GC_UNTRACK (self );
116127 PyBuffer_Release (& self -> master );
@@ -1109,12 +1120,17 @@ static void
11091120_memory_release (PyMemoryViewObject * self )
11101121{
11111122 assert (get_exports (self ) == 0 );
1112- if (self -> flags & _Py_MEMORYVIEW_RELEASED )
1123+ int prev_flags = atomic_or (& self -> flags , _Py_MEMORYVIEW_RELEASED );
1124+ if (prev_flags & _Py_MEMORYVIEW_RELEASED )
11131125 return ;
11141126
1115- self -> flags |= _Py_MEMORYVIEW_RELEASED ;
1116- assert (self -> mbuf -> exports > 0 );
1117- if (-- self -> mbuf -> exports == 0 ) {
1127+ #ifdef Py_GIL_DISABLED
1128+ Py_ssize_t prev_exports = _Py_atomic_add_ssize (& self -> mbuf -> exports , -1 );
1129+ #else
1130+ Py_ssize_t prev_exports = self -> mbuf -> exports -- ;
1131+ #endif
1132+ assert (prev_exports > 0 );
1133+ if (prev_exports == 1 ) {
11181134 mbuf_release (self -> mbuf );
11191135 }
11201136}
0 commit comments