mirror of
https://github.com/python/cpython.git
synced 2025-08-22 09:45:06 +00:00
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.
This commit is contained in:
parent
48b069a003
commit
87255be696
7 changed files with 133 additions and 22 deletions
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue