summaryrefslogtreecommitdiffstats
path: root/Lib/threading.py
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-04-07 21:11:49 (GMT)
committerGitHub <noreply@github.com>2020-04-07 21:11:49 (GMT)
commit87255be6964979b5abdc4b9dcf81cdcfdad6e753 (patch)
tree30f3c5a680dd7ed6435841ecd38166de7654503e /Lib/threading.py
parent48b069a003ba6c684a9ba78493fbbec5e89f10b8 (diff)
downloadcpython-87255be6964979b5abdc4b9dcf81cdcfdad6e753.zip
cpython-87255be6964979b5abdc4b9dcf81cdcfdad6e753.tar.gz
cpython-87255be6964979b5abdc4b9dcf81cdcfdad6e753.tar.bz2
bpo-40089: Add _at_fork_reinit() method to locks (GH-19195)
Add a private _at_fork_reinit() method to _thread.Lock, _thread.RLock, threading.RLock and threading.Condition classes: reinitialize the lock after fork in the child process; reset the lock to the unlocked state. Rename also the private _reset_internal_locks() method of threading.Event to _at_fork_reinit(). * Add _PyThread_at_fork_reinit() private function. It is excluded from the limited C API. * threading.Thread._reset_internal_locks() now calls _at_fork_reinit() on self._tstate_lock rather than creating a new Python lock object.
Diffstat (limited to 'Lib/threading.py')
-rw-r--r--Lib/threading.py20
1 files changed, 15 insertions, 5 deletions
diff --git a/Lib/threading.py b/Lib/threading.py
index 6b25e7a..5424db3 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -123,6 +123,11 @@ class _RLock:
hex(id(self))
)
+ def _at_fork_reinit(self):
+ self._block._at_fork_reinit()
+ self._owner = None
+ self._count = 0
+
def acquire(self, blocking=True, timeout=-1):
"""Acquire a lock, blocking or non-blocking.
@@ -245,6 +250,10 @@ class Condition:
pass
self._waiters = _deque()
+ def _at_fork_reinit(self):
+ self._lock._at_fork_reinit()
+ self._waiters.clear()
+
def __enter__(self):
return self._lock.__enter__()
@@ -514,9 +523,9 @@ class Event:
self._cond = Condition(Lock())
self._flag = False
- def _reset_internal_locks(self):
- # private! called by Thread._reset_internal_locks by _after_fork()
- self._cond.__init__(Lock())
+ def _at_fork_reinit(self):
+ # Private method called by Thread._reset_internal_locks()
+ self._cond._at_fork_reinit()
def is_set(self):
"""Return true if and only if the internal flag is true."""
@@ -816,9 +825,10 @@ class Thread:
def _reset_internal_locks(self, is_alive):
# private! Called by _after_fork() to reset our internal locks as
# they may be in an invalid state leading to a deadlock or crash.
- self._started._reset_internal_locks()
+ self._started._at_fork_reinit()
if is_alive:
- self._set_tstate_lock()
+ self._tstate_lock._at_fork_reinit()
+ self._tstate_lock.acquire()
else:
# The thread isn't alive after fork: it doesn't have a tstate
# anymore.