@@ -711,8 +711,9 @@ def _terminate_pool(cls, taskqueue, inqueue, outqueue, pool, change_notifier,
711711 change_notifier .put (None )
712712
713713 task_handler ._state = TERMINATE
714- # Release all semaphores to wake up task_handler to stop.
715- for buffersize_sema in tuple (taskqueue_buffersize_semaphores ):
714+ # Snapshot the set before releasing semaphores: the result handler can
715+ # remove completed ones concurrently.
716+ for buffersize_sema in list (taskqueue_buffersize_semaphores ):
716717 buffersize_sema .release ()
717718 taskqueue_buffersize_semaphores .discard (buffersize_sema )
718719
@@ -935,11 +936,13 @@ def next(self, timeout=None):
935936 return value
936937 raise value
937938
938- def _stop_iterator (self ):
939+ def _release_pool (self ):
939940 if self ._pool is not None :
940- # `self._pool` could be set to `None` in previous `.next()` calls
941941 self ._pool ._taskqueue_buffersize_semaphores .discard (self ._buffersize_sema )
942942 self ._pool = None
943+
944+ def _stop_iterator (self ):
945+ self ._release_pool ()
943946 raise StopIteration from None
944947
945948 __next__ = next # XXX
@@ -959,15 +962,15 @@ def _set(self, i, obj):
959962
960963 if self ._index == self ._length :
961964 del self ._cache [self ._job ]
962- self ._pool = None
965+ self ._release_pool ()
963966
964967 def _set_length (self , length ):
965968 with self ._cond :
966969 self ._length = length
967970 if self ._index == self ._length :
968971 self ._cond .notify ()
969972 del self ._cache [self ._job ]
970- self ._pool = None
973+ self ._release_pool ()
971974
972975#
973976# Class whose instances are returned by `Pool.imap_unordered()`
@@ -982,7 +985,7 @@ def _set(self, i, obj):
982985 self ._cond .notify ()
983986 if self ._index == self ._length :
984987 del self ._cache [self ._job ]
985- self ._pool = None
988+ self ._release_pool ()
986989
987990#
988991#
0 commit comments