summaryrefslogtreecommitdiffstats
path: root/Lib/multiprocessing
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/multiprocessing')
-rw-r--r--Lib/multiprocessing/util.py34
1 files changed, 21 insertions, 13 deletions
diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py
index 0ce274c..b490caa 100644
--- a/Lib/multiprocessing/util.py
+++ b/Lib/multiprocessing/util.py
@@ -241,20 +241,28 @@ def _run_finalizers(minpriority=None):
return
if minpriority is None:
- f = lambda p : p[0][0] is not None
+ f = lambda p : p[0] is not None
else:
- f = lambda p : p[0][0] is not None and p[0][0] >= minpriority
-
- items = [x for x in list(_finalizer_registry.items()) if f(x)]
- items.sort(reverse=True)
-
- for key, finalizer in items:
- sub_debug('calling %s', finalizer)
- try:
- finalizer()
- except Exception:
- import traceback
- traceback.print_exc()
+ f = lambda p : p[0] is not None and p[0] >= minpriority
+
+ # Careful: _finalizer_registry may be mutated while this function
+ # is running (either by a GC run or by another thread).
+
+ # list(_finalizer_registry) should be atomic, while
+ # list(_finalizer_registry.items()) is not.
+ keys = [key for key in list(_finalizer_registry) if f(key)]
+ keys.sort(reverse=True)
+
+ for key in keys:
+ finalizer = _finalizer_registry.get(key)
+ # key may have been removed from the registry
+ if finalizer is not None:
+ sub_debug('calling %s', finalizer)
+ try:
+ finalizer()
+ except Exception:
+ import traceback
+ traceback.print_exc()
if minpriority is None:
_finalizer_registry.clear()