@@ -104,20 +104,24 @@ _PyManagedBuffer_FromObject(PyObject *base, int flags)
104104}
105105
106106static inline int
107- flags_test_and_set (int * flags , int bit )
107+ flags_set_released (int * flags , int released )
108108{
109109#ifdef Py_GIL_DISABLED
110110 int prev = _Py_atomic_load_int_relaxed (flags );
111- while (!_Py_atomic_compare_exchange_int (flags , & prev , prev | bit )) {
112- // Compare-exchange updates prev. Note that retries are bounded by the
113- // number of flag bits being concurrently set. So, yielding here is
114- // unnecessary.
111+ if (prev & released ) {
112+ return 1 ;
115113 }
114+ if (!_Py_atomic_compare_exchange_int (flags , & prev , prev | released )) {
115+ // RELEASED is the only flag that can change concurrently.
116+ assert (prev & released );
117+ return 1 ;
118+ }
119+ return 0 ;
116120#else
117121 int prev = * flags ;
118- * flags = prev | bit ;
122+ * flags = prev | released ;
123+ return (prev & released ) != 0 ;
119124#endif
120- return (prev & bit ) != 0 ;
121125}
122126
123127static inline int
@@ -133,9 +137,9 @@ mv_has_flag(PyMemoryViewObject *mv, int bits)
133137}
134138
135139static inline int
136- mv_set_flag (PyMemoryViewObject * mv , int bit )
140+ mv_set_released (PyMemoryViewObject * mv )
137141{
138- return flags_test_and_set (& mv -> flags , bit );
142+ return flags_set_released (& mv -> flags , _Py_MEMORYVIEW_RELEASED );
139143}
140144
141145static inline int
@@ -145,15 +149,15 @@ mbuf_has_flag(_PyManagedBufferObject *mbuf, int bits)
145149}
146150
147151static inline int
148- mbuf_set_flag (_PyManagedBufferObject * mbuf , int bit )
152+ mbuf_set_released (_PyManagedBufferObject * mbuf )
149153{
150- return flags_test_and_set (& mbuf -> flags , bit );
154+ return flags_set_released (& mbuf -> flags , _Py_MANAGED_BUFFER_RELEASED );
151155}
152156
153157static void
154158mbuf_release (_PyManagedBufferObject * self )
155159{
156- if (mbuf_set_flag (self , _Py_MANAGED_BUFFER_RELEASED )) {
160+ if (mbuf_set_released (self )) {
157161 return ;
158162 }
159163
@@ -1227,7 +1231,7 @@ static void
12271231_memory_release (PyMemoryViewObject * self )
12281232{
12291233 assert (get_exports (self ) == 0 );
1230- if (mv_set_flag (self , _Py_MEMORYVIEW_RELEASED )) {
1234+ if (mv_set_released (self )) {
12311235 return ;
12321236 }
12331237
0 commit comments