@@ -108,8 +108,6 @@ mbuf_release(_PyManagedBufferObject *self)
108108 if (self -> flags & _Py_MANAGED_BUFFER_RELEASED )
109109 return ;
110110
111- /* NOTE: at this point self->exports can still be > 0 if this function
112- is called from mbuf_clear() to break up a reference cycle. */
113111 self -> flags |= _Py_MANAGED_BUFFER_RELEASED ;
114112
115113 /* PyBuffer_Release() decrements master->obj and sets it to NULL. */
@@ -1092,32 +1090,19 @@ PyBuffer_ToContiguous(void *buf, const Py_buffer *src, Py_ssize_t len, char orde
10921090/* Inform the managed buffer that this particular memoryview will not access
10931091 the underlying buffer again. If no other memoryviews are registered with
10941092 the managed buffer, the underlying buffer is released instantly and
1095- marked as inaccessible for both the memoryview and the managed buffer.
1096-
1097- This function fails if the memoryview itself has exported buffers. */
1098- static int
1093+ marked as inaccessible for both the memoryview and the managed buffer. */
1094+ static void
10991095_memory_release (PyMemoryViewObject * self )
11001096{
1097+ assert (self -> exports == 0 );
11011098 if (self -> flags & _Py_MEMORYVIEW_RELEASED )
1102- return 0 ;
1099+ return ;
11031100
1104- if (self -> exports == 0 ) {
1105- self -> flags |= _Py_MEMORYVIEW_RELEASED ;
1106- assert (self -> mbuf -> exports > 0 );
1107- if (-- self -> mbuf -> exports == 0 )
1108- mbuf_release (self -> mbuf );
1109- return 0 ;
1101+ self -> flags |= _Py_MEMORYVIEW_RELEASED ;
1102+ assert (self -> mbuf -> exports > 0 );
1103+ if (-- self -> mbuf -> exports == 0 ) {
1104+ mbuf_release (self -> mbuf );
11101105 }
1111- if (self -> exports > 0 ) {
1112- PyErr_Format (PyExc_BufferError ,
1113- "memoryview has %zd exported buffer%s" , self -> exports ,
1114- self -> exports == 1 ? "" : "s" );
1115- return -1 ;
1116- }
1117-
1118- PyErr_SetString (PyExc_SystemError ,
1119- "_memory_release(): negative export count" );
1120- return -1 ;
11211106}
11221107
11231108/*[clinic input]
@@ -1130,17 +1115,29 @@ static PyObject *
11301115memoryview_release_impl (PyMemoryViewObject * self )
11311116/*[clinic end generated code: output=d0b7e3ba95b7fcb9 input=bc71d1d51f4a52f0]*/
11321117{
1133- if (_memory_release (self ) < 0 )
1118+ if (self -> exports == 0 ) {
1119+ _memory_release (self );
1120+ Py_RETURN_NONE ;
1121+ }
1122+
1123+ if (self -> exports > 0 ) {
1124+ PyErr_Format (PyExc_BufferError ,
1125+ "memoryview has %zd exported buffer%s" , self -> exports ,
1126+ self -> exports == 1 ? "" : "s" );
11341127 return NULL ;
1135- Py_RETURN_NONE ;
1128+ }
1129+
1130+ PyErr_SetString (PyExc_SystemError ,
1131+ "memoryview: negative export count" );
1132+ return NULL ;
11361133}
11371134
11381135static void
11391136memory_dealloc (PyMemoryViewObject * self )
11401137{
11411138 assert (self -> exports == 0 );
11421139 _PyObject_GC_UNTRACK (self );
1143- ( void ) _memory_release (self );
1140+ _memory_release (self );
11441141 Py_CLEAR (self -> mbuf );
11451142 if (self -> weakreflist != NULL )
11461143 PyObject_ClearWeakRefs ((PyObject * ) self );
@@ -1157,8 +1154,10 @@ memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
11571154static int
11581155memory_clear (PyMemoryViewObject * self )
11591156{
1160- (void )_memory_release (self );
1161- Py_CLEAR (self -> mbuf );
1157+ if (self -> exports == 0 ) {
1158+ _memory_release (self );
1159+ Py_CLEAR (self -> mbuf );
1160+ }
11621161 return 0 ;
11631162}
11641163
0 commit comments