diff options
| author | shadchin <[email protected]> | 2023-10-03 23:32:21 +0300 |
|---|---|---|
| committer | shadchin <[email protected]> | 2023-10-03 23:48:51 +0300 |
| commit | 01ffd024041ac933854c367fb8d1b5682d19883f (patch) | |
| tree | b70aa497ba132a133ccece49f7763427dcd0743f /contrib/tools/python3/src/Lib/concurrent | |
| parent | a33fdb9a34581fd124e92535153b1f1fdeca6aaf (diff) | |
Update Python 3 to 3.11.6
Diffstat (limited to 'contrib/tools/python3/src/Lib/concurrent')
| -rw-r--r-- | contrib/tools/python3/src/Lib/concurrent/futures/process.py | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/contrib/tools/python3/src/Lib/concurrent/futures/process.py b/contrib/tools/python3/src/Lib/concurrent/futures/process.py index 321608ab174..952fa903457 100644 --- a/contrib/tools/python3/src/Lib/concurrent/futures/process.py +++ b/contrib/tools/python3/src/Lib/concurrent/futures/process.py @@ -69,6 +69,11 @@ class _ThreadWakeup: self._reader, self._writer = mp.Pipe(duplex=False) def close(self): + # Please note that we do not take the shutdown lock when + # calling clear() (to avoid deadlocking) so this method can + # only be called safely from the same thread as all calls to + # clear() even if you hold the shutdown lock. Otherwise we + # might try to read from the closed pipe. if not self._closed: self._closed = True self._writer.close() @@ -424,8 +429,12 @@ class _ExecutorManagerThread(threading.Thread): elif wakeup_reader in ready: is_broken = False - with self.shutdown_lock: - self.thread_wakeup.clear() + # No need to hold the _shutdown_lock here because: + # 1. we're the only thread to use the wakeup reader + # 2. we're also the only thread to call thread_wakeup.close() + # 3. we want to avoid a possible deadlock when both reader and writer + # would block (gh-105829) + self.thread_wakeup.clear() return result_item, is_broken, cause @@ -501,6 +510,11 @@ class _ExecutorManagerThread(threading.Thread): # https://github.com/python/cpython/issues/94777 self.call_queue._reader.close() + # gh-107219: Close the connection writer which can unblock + # Queue._feed() if it was stuck in send_bytes(). + if sys.platform == 'win32': + self.call_queue._writer.close() + # clean up resources self.join_executor_internals() @@ -704,7 +718,10 @@ class ProcessPoolExecutor(_base.Executor): # as it could result in a deadlock if a worker process dies with the # _result_queue write lock still acquired. # - # _shutdown_lock must be locked to access _ThreadWakeup. + # _shutdown_lock must be locked to access _ThreadWakeup.close() and + # .wakeup(). Care must also be taken to not call clear or close from + # more than one thread since _ThreadWakeup.clear() is not protected by + # the _shutdown_lock self._executor_manager_thread_wakeup = _ThreadWakeup() # Create communication channels for the executor |
