@@ -825,32 +825,31 @@ mbuf_drop_export(_PyManagedBufferObject *mbuf)
825825 free the underlying buffer while the operation is running. The pin does
826826 not hold a reference to the managed buffer: the memoryview's own
827827 reference is kept until memory_dealloc(), and the caller holds a
828- reference to the memoryview. On success, return the pinned managed
829- buffer; pass it to memoryview_unpin() afterwards. On failure, set an
830- exception and return NULL. */
831- static inline _PyManagedBufferObject *
828+ reference to the memoryview through memoryview_unpin(self). Return 0
829+ on success and -1 with an exception on failure. */
830+ static inline int
832831memoryview_pin (PyMemoryViewObject * self )
833832{
834833 if (mv_has_flag (self , _Py_MEMORYVIEW_RELEASED )) {
835834 PyErr_SetString (PyExc_ValueError ,
836835 "operation forbidden on released memoryview object" );
837- return NULL ;
836+ return -1 ;
838837 }
839838 _PyManagedBufferObject * mbuf = self -> mbuf ;
840839 FT_ATOMIC_ADD_SSIZE (mbuf -> exports , 1 );
841840 if (BASE_INACCESSIBLE (self )) {
842841 mbuf_drop_export (mbuf );
843842 PyErr_SetString (PyExc_ValueError ,
844843 "operation forbidden on released memoryview object" );
845- return NULL ;
844+ return -1 ;
846845 }
847- return mbuf ;
846+ return 0 ;
848847}
849848
850849static inline void
851- memoryview_unpin (_PyManagedBufferObject * mbuf )
850+ memoryview_unpin (PyMemoryViewObject * self )
852851{
853- mbuf_drop_export (mbuf );
852+ mbuf_drop_export (self -> mbuf );
854853}
855854
856855/* Expose a raw memory area as a view of contiguous bytes. flags can be
@@ -923,8 +922,7 @@ PyMemoryView_FromObjectAndFlags(PyObject *v, int flags)
923922
924923 if (PyMemoryView_Check (v )) {
925924 PyMemoryViewObject * mv = (PyMemoryViewObject * )v ;
926- _PyManagedBufferObject * mv_mbuf = memoryview_pin (mv );
927- if (mv_mbuf == NULL ) {
925+ if (memoryview_pin (mv ) < 0 ) {
928926 return NULL ;
929927 }
930928 PyObject * result ;
@@ -934,9 +932,9 @@ PyMemoryView_FromObjectAndFlags(PyObject *v, int flags)
934932 result = NULL ;
935933 }
936934 else {
937- result = mbuf_add_view (mv_mbuf , & mv -> view );
935+ result = mbuf_add_view (mv -> mbuf , & mv -> view );
938936 }
939- memoryview_unpin (mv_mbuf );
937+ memoryview_unpin (mv );
940938 return result ;
941939 }
942940 else if (PyObject_CheckBuffer (v )) {
@@ -1691,12 +1689,11 @@ memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format,
16911689 PyObject * shape , int order )
16921690/*[clinic end generated code: output=6410d87141f6bb56 input=4a1a2326c59caeb3]*/
16931691{
1694- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
1695- if (self_mbuf == NULL ) {
1692+ if (memoryview_pin (self ) < 0 ) {
16961693 return NULL ;
16971694 }
16981695 PyObject * result = memoryview_cast_pinned (self , format , shape , order );
1699- memoryview_unpin (self_mbuf );
1696+ memoryview_unpin (self );
17001697 return result ;
17011698}
17021699
@@ -1725,12 +1722,11 @@ static PyObject *
17251722memoryview_toreadonly_impl (PyMemoryViewObject * self )
17261723/*[clinic end generated code: output=2c7e056f04c99e62 input=dc06d20f19ba236f]*/
17271724{
1728- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
1729- if (self_mbuf == NULL ) {
1725+ if (memoryview_pin (self ) < 0 ) {
17301726 return NULL ;
17311727 }
17321728 PyObject * result = memoryview_toreadonly_pinned (self );
1733- memoryview_unpin (self_mbuf );
1729+ memoryview_unpin (self );
17341730 return result ;
17351731}
17361732
@@ -2540,12 +2536,11 @@ static PyObject *
25402536memoryview_tolist_impl (PyMemoryViewObject * self )
25412537/*[clinic end generated code: output=a6cda89214fd5a1b input=21e7d0c1860b211a]*/
25422538{
2543- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
2544- if (self_mbuf == NULL ) {
2539+ if (memoryview_pin (self ) < 0 ) {
25452540 return NULL ;
25462541 }
25472542 PyObject * result = memoryview_tolist_pinned (self );
2548- memoryview_unpin (self_mbuf );
2543+ memoryview_unpin (self );
25492544 return result ;
25502545}
25512546
@@ -2605,12 +2600,11 @@ static PyObject *
26052600memoryview_tobytes_impl (PyMemoryViewObject * self , const char * order )
26062601/*[clinic end generated code: output=1288b62560a32a23 input=119c70aa91791dc8]*/
26072602{
2608- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
2609- if (self_mbuf == NULL ) {
2603+ if (memoryview_pin (self ) < 0 ) {
26102604 return NULL ;
26112605 }
26122606 PyObject * result = memoryview_tobytes_pinned (self , order );
2613- memoryview_unpin (self_mbuf );
2607+ memoryview_unpin (self );
26142608 return result ;
26152609}
26162610
@@ -2684,12 +2678,11 @@ memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep,
26842678 Py_ssize_t bytes_per_sep )
26852679/*[clinic end generated code: output=c9bb00c7a8e86056 input=3f1c5d08906e3b70]*/
26862680{
2687- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
2688- if (self_mbuf == NULL ) {
2681+ if (memoryview_pin (self ) < 0 ) {
26892682 return NULL ;
26902683 }
26912684 PyObject * result = memoryview_hex_pinned (self , sep , bytes_per_sep );
2692- memoryview_unpin (self_mbuf );
2685+ memoryview_unpin (self );
26932686 return result ;
26942687}
26952688
@@ -3080,38 +3073,35 @@ static PyObject *
30803073memory_item (PyObject * _self , Py_ssize_t index )
30813074{
30823075 PyMemoryViewObject * self = (PyMemoryViewObject * )_self ;
3083- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
3084- if (self_mbuf == NULL ) {
3076+ if (memoryview_pin (self ) < 0 ) {
30853077 return NULL ;
30863078 }
30873079 PyObject * result = memory_item_pinned (_self , index );
3088- memoryview_unpin (self_mbuf );
3080+ memoryview_unpin (self );
30893081 return result ;
30903082}
30913083
30923084static PyObject *
30933085memory_subscript (PyObject * _self , PyObject * key )
30943086{
30953087 PyMemoryViewObject * self = (PyMemoryViewObject * )_self ;
3096- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
3097- if (self_mbuf == NULL ) {
3088+ if (memoryview_pin (self ) < 0 ) {
30983089 return NULL ;
30993090 }
31003091 PyObject * result = memory_subscript_pinned (_self , key );
3101- memoryview_unpin (self_mbuf );
3092+ memoryview_unpin (self );
31023093 return result ;
31033094}
31043095
31053096static int
31063097memory_ass_sub (PyObject * _self , PyObject * key , PyObject * value )
31073098{
31083099 PyMemoryViewObject * self = (PyMemoryViewObject * )_self ;
3109- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
3110- if (self_mbuf == NULL ) {
3100+ if (memoryview_pin (self ) < 0 ) {
31113101 return -1 ;
31123102 }
31133103 int result = memory_ass_sub_pinned (_self , key , value );
3114- memoryview_unpin (self_mbuf );
3104+ memoryview_unpin (self );
31153105 return result ;
31163106}
31173107
@@ -3182,12 +3172,11 @@ static PyObject *
31823172memoryview_count_impl (PyMemoryViewObject * self , PyObject * value )
31833173/*[clinic end generated code: output=a15cb19311985063 input=e3036ce1ed7d1823]*/
31843174{
3185- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
3186- if (self_mbuf == NULL ) {
3175+ if (memoryview_pin (self ) < 0 ) {
31873176 return NULL ;
31883177 }
31893178 PyObject * result = memoryview_count_pinned (self , value );
3190- memoryview_unpin (self_mbuf );
3179+ memoryview_unpin (self );
31913180 return result ;
31923181}
31933182
@@ -3282,12 +3271,11 @@ memoryview_index_impl(PyMemoryViewObject *self, PyObject *value,
32823271 Py_ssize_t start , Py_ssize_t stop )
32833272/*[clinic end generated code: output=e0185e3819e549df input=0697a0165bf90b5a]*/
32843273{
3285- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
3286- if (self_mbuf == NULL ) {
3274+ if (memoryview_pin (self ) < 0 ) {
32873275 return NULL ;
32883276 }
32893277 PyObject * result = memoryview_index_pinned (self , value , start , stop );
3290- memoryview_unpin (self_mbuf );
3278+ memoryview_unpin (self );
32913279 return result ;
32923280}
32933281
@@ -3636,30 +3624,27 @@ static PyObject *
36363624memory_richcompare (PyObject * v , PyObject * w , int op )
36373625{
36383626 PyMemoryViewObject * self = (PyMemoryViewObject * )v ;
3639- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
3640- if (self_mbuf == NULL ) {
3627+ if (memoryview_pin (self ) < 0 ) {
36413628 /* Released memoryviews still compare by identity. */
36423629 PyErr_Clear ();
36433630 return memory_richcompare_pinned (v , w , op );
36443631 }
36453632
36463633 PyMemoryViewObject * other = NULL ;
3647- _PyManagedBufferObject * other_mbuf = NULL ;
36483634 if (PyMemoryView_Check (w ) && w != v ) {
36493635 other = (PyMemoryViewObject * )w ;
3650- other_mbuf = memoryview_pin (other );
3651- if (other_mbuf == NULL ) {
3636+ if (memoryview_pin (other ) < 0 ) {
36523637 PyErr_Clear ();
3653- memoryview_unpin (self_mbuf );
3638+ memoryview_unpin (self );
36543639 return memory_richcompare_pinned (v , w , op );
36553640 }
36563641 }
36573642
36583643 PyObject * result = memory_richcompare_pinned (v , w , op );
36593644 if (other != NULL ) {
3660- memoryview_unpin (other_mbuf );
3645+ memoryview_unpin (other );
36613646 }
3662- memoryview_unpin (self_mbuf );
3647+ memoryview_unpin (self );
36633648 return result ;
36643649}
36653650
@@ -3740,12 +3725,11 @@ memory_hash(PyObject *_self)
37403725 if (hash != -1 ) {
37413726 return hash ;
37423727 }
3743- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
3744- if (self_mbuf == NULL ) {
3728+ if (memoryview_pin (self ) < 0 ) {
37453729 return -1 ;
37463730 }
37473731 Py_hash_t result = memory_hash_pinned (_self );
3748- memoryview_unpin (self_mbuf );
3732+ memoryview_unpin (self );
37493733 return result ;
37503734}
37513735
@@ -3884,12 +3868,11 @@ memory_contiguous(PyObject *_self, void *Py_UNUSED(ignored))
38843868 name(PyObject *_self, void *ignored) \
38853869 { \
38863870 PyMemoryViewObject *self = (PyMemoryViewObject *)_self; \
3887- _PyManagedBufferObject *mbuf = memoryview_pin(self); \
3888- if (mbuf == NULL) { \
3871+ if (memoryview_pin(self) < 0) { \
38893872 return NULL; \
38903873 } \
38913874 PyObject *result = name##_pinned(_self, ignored); \
3892- memoryview_unpin(mbuf ); \
3875+ memoryview_unpin(self ); \
38933876 return result; \
38943877 }
38953878
@@ -3996,37 +3979,57 @@ static PyObject *
39963979memoryiter_next (PyObject * self )
39973980{
39983981 memoryiterobject * it = (memoryiterobject * )self ;
3999- PyMemoryViewObject * seq = it -> it_seq ;
4000- if (seq == NULL ) {
3982+ PyMemoryViewObject * seq ;
3983+ Py_ssize_t index ;
3984+
3985+ Py_BEGIN_CRITICAL_SECTION (it );
3986+ seq = it -> it_seq ;
3987+ index = it -> it_index ;
3988+ if (seq != NULL ) {
3989+ if (index >= it -> it_length ) {
3990+ /* Transfer the iterator's reference to seq before clearing it. */
3991+ it -> it_seq = NULL ;
3992+ }
3993+ else {
3994+ Py_INCREF (seq );
3995+ }
3996+ }
3997+ Py_END_CRITICAL_SECTION ();
3998+
3999+ if (seq == NULL || index >= it -> it_length ) {
4000+ Py_XDECREF (seq );
40014001 return NULL ;
40024002 }
40034003
4004- if (it -> it_index >= it -> it_length ) {
4005- /* Preserve StopIteration for exhausted iterators over released views. */
4006- #ifndef Py_GIL_DISABLED
4007- /* Like list and tuple iterators, keep the reference in the
4008- free-threaded build: clearing it here races with other threads
4009- that are still using seq. */
4010- it -> it_seq = NULL ;
4004+ /* Pin outside the iterator lock: a failed pin may release the buffer. */
4005+ if (memoryview_pin (seq ) < 0 ) {
40114006 Py_DECREF (seq );
4012- #endif
40134007 return NULL ;
40144008 }
40154009
4016- _PyManagedBufferObject * mbuf = memoryview_pin (seq );
4017- if (mbuf == NULL ) {
4010+ Py_BEGIN_CRITICAL_SECTION (it );
4011+ index = it -> it_index ;
4012+ if (index < it -> it_length ) {
4013+ it -> it_index = index + 1 ;
4014+ }
4015+ Py_END_CRITICAL_SECTION ();
4016+ if (index >= it -> it_length ) {
4017+ memoryview_unpin (seq );
4018+ Py_DECREF (seq );
40184019 return NULL ;
40194020 }
4021+
40204022 Py_buffer * view = & seq -> view ;
40214023 char * ptr = (char * )view -> buf ;
40224024
4023- ptr += view -> strides [0 ] * it -> it_index ++ ;
4025+ ptr += view -> strides [0 ] * index ;
40244026 ptr = ADJUST_PTR (ptr , view -> suboffsets , 0 );
40254027 PyObject * result = NULL ;
40264028 if (ptr != NULL ) {
40274029 result = unpack_single (seq , ptr , it -> it_fmt );
40284030 }
4029- memoryview_unpin (mbuf );
4031+ memoryview_unpin (seq );
4032+ Py_DECREF (seq );
40304033 return result ;
40314034}
40324035
@@ -4072,12 +4075,11 @@ static PyObject *
40724075memory_iter (PyObject * seq )
40734076{
40744077 PyMemoryViewObject * self = (PyMemoryViewObject * )seq ;
4075- _PyManagedBufferObject * self_mbuf = memoryview_pin (self );
4076- if (self_mbuf == NULL ) {
4078+ if (memoryview_pin (self ) < 0 ) {
40774079 return NULL ;
40784080 }
40794081 PyObject * result = memory_iter_pinned (seq );
4080- memoryview_unpin (self_mbuf );
4082+ memoryview_unpin (self );
40814083 return result ;
40824084}
40834085
0 commit comments