mirror of https://github.com/python/cpython
gh-107219: Fix concurrent.futures terminate_broken() (#108974)
Fix a race condition in _ExecutorManagerThread.terminate_broken(): ignore the InvalidStateError on future.set_exception(). It can happen if the future is cancelled before the caller. Moreover, test_crash_big_data() now waits explicitly until the executor completes.
This commit is contained in:
parent
b298b395e8
commit
a8cae4071c
|
@ -489,7 +489,14 @@ class _ExecutorManagerThread(threading.Thread):
|
||||||
|
|
||||||
# Mark pending tasks as failed.
|
# Mark pending tasks as failed.
|
||||||
for work_id, work_item in self.pending_work_items.items():
|
for work_id, work_item in self.pending_work_items.items():
|
||||||
work_item.future.set_exception(bpe)
|
try:
|
||||||
|
work_item.future.set_exception(bpe)
|
||||||
|
except _base.InvalidStateError as exc:
|
||||||
|
# set_exception() fails if the future is cancelled: ignore it.
|
||||||
|
# Trying to check if the future is cancelled before calling
|
||||||
|
# set_exception() would leave a race condition if the future is
|
||||||
|
# cancelled betwen the check and set_exception().
|
||||||
|
pass
|
||||||
# Delete references to object. See issue16284
|
# Delete references to object. See issue16284
|
||||||
del work_item
|
del work_item
|
||||||
self.pending_work_items.clear()
|
self.pending_work_items.clear()
|
||||||
|
|
|
@ -239,6 +239,8 @@ class ExecutorDeadlockTest:
|
||||||
with self.assertRaises(BrokenProcessPool):
|
with self.assertRaises(BrokenProcessPool):
|
||||||
list(executor.map(_crash_with_data, [data] * 10))
|
list(executor.map(_crash_with_data, [data] * 10))
|
||||||
|
|
||||||
|
executor.shutdown(wait=True)
|
||||||
|
|
||||||
|
|
||||||
create_executor_tests(globals(), ExecutorDeadlockTest,
|
create_executor_tests(globals(), ExecutorDeadlockTest,
|
||||||
executor_mixins=(ProcessPoolForkMixin,
|
executor_mixins=(ProcessPoolForkMixin,
|
||||||
|
|
Loading…
Reference in New Issue