summaryrefslogtreecommitdiffstats
path: root/Lib/threading.py
diff options
context:
space:
mode:
authorJesse Noller <jnoller@gmail.com>2008-07-16 20:03:47 (GMT)
committerJesse Noller <jnoller@gmail.com>2008-07-16 20:03:47 (GMT)
commit5e62ca4fea04ad7b349330c50dc11937ab3278f4 (patch)
tree3a37b08db904d9e9239b7d08f630f24c46569a61 /Lib/threading.py
parent1bbf4ea553a5089ec82377dd24531dd79e3357c6 (diff)
downloadcpython-5e62ca4fea04ad7b349330c50dc11937ab3278f4.zip
cpython-5e62ca4fea04ad7b349330c50dc11937ab3278f4.tar.gz
cpython-5e62ca4fea04ad7b349330c50dc11937ab3278f4.tar.bz2
Apply patch for 874900: threading module can deadlock after fork
Diffstat (limited to 'Lib/threading.py')
-rw-r--r--Lib/threading.py31
1 files changed, 31 insertions, 0 deletions
diff --git a/Lib/threading.py b/Lib/threading.py
index bfca44c..8a1de42 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -825,6 +825,37 @@ except ImportError:
from _threading_local import local
+def _after_fork():
+ # This function is called by Python/ceval.c:PyEval_ReInitThreads which
+ # is called from PyOS_AfterFork. Here we cleanup threading module state
+ # that should not exist after a fork.
+
+ # Reset _active_limbo_lock, in case we forked while the lock was held
+ # by another (non-forked) thread. http://bugs.python.org/issue874900
+ global _active_limbo_lock
+ _active_limbo_lock = _allocate_lock()
+
+ # fork() only copied the current thread; clear references to others.
+ new_active = {}
+ current = current_thread()
+ with _active_limbo_lock:
+ for ident, thread in _active.iteritems():
+ if thread is current:
+ # There is only one active thread.
+ new_active[ident] = thread
+ else:
+ # All the others are already stopped.
+ # We don't call _Thread__stop() because it tries to acquire
+ # thread._Thread__block which could also have been held while
+ # we forked.
+ thread._Thread__stopped = True
+
+ _limbo.clear()
+ _active.clear()
+ _active.update(new_active)
+ assert len(_active) == 1
+
+
# Self-test code
def _test():