Skip to content

Commit b68565c

Browse files
committed
Don't clear memoryview iterator's reference on exhaustion in free-threaded build
1 parent e8a9aa5 commit b68565c

1 file changed

Lines changed: 16 additions & 18 deletions

File tree

‎Objects/memoryobject.c‎

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4003,32 +4003,30 @@ memoryiter_next(PyObject *self)
40034003

40044004
if (it->it_index >= it->it_length) {
40054005
/* 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. */
40064010
it->it_seq = NULL;
40074011
Py_DECREF(seq);
4012+
#endif
40084013
return NULL;
40094014
}
40104015

4011-
#ifdef Py_GIL_DISABLED
4012-
/* Keep seq alive if another thread exhausts the iterator. */
4013-
Py_INCREF(seq);
4014-
#endif
4016+
_PyManagedBufferObject *mbuf = memoryview_pin(seq);
4017+
if (mbuf == NULL) {
4018+
return NULL;
4019+
}
4020+
Py_buffer *view = &seq->view;
4021+
char *ptr = (char *)view->buf;
40154022

4023+
ptr += view->strides[0] * it->it_index++;
4024+
ptr = ADJUST_PTR(ptr, view->suboffsets, 0);
40164025
PyObject *result = NULL;
4017-
if (memoryview_pin(seq) == 0) {
4018-
Py_buffer *view = &seq->view;
4019-
char *ptr = (char *)view->buf;
4020-
4021-
ptr += view->strides[0] * it->it_index++;
4022-
ptr = ADJUST_PTR(ptr, view->suboffsets, 0);
4023-
if (ptr != NULL) {
4024-
result = unpack_single(seq, ptr, it->it_fmt);
4025-
}
4026-
memoryview_unpin(seq);
4026+
if (ptr != NULL) {
4027+
result = unpack_single(seq, ptr, it->it_fmt);
40274028
}
4028-
4029-
#ifdef Py_GIL_DISABLED
4030-
Py_DECREF(seq);
4031-
#endif
4029+
memoryview_unpin(mbuf);
40324030
return result;
40334031
}
40344032

0 commit comments

Comments
 (0)