mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +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
|
@ -693,6 +693,26 @@ PyThread_release_lock(PyThread_type_lock lock)
|
|||
|
||||
#endif /* USE_SEMAPHORES */
|
||||
|
||||
int
|
||||
_PyThread_at_fork_reinit(PyThread_type_lock *lock)
|
||||
{
|
||||
PyThread_type_lock new_lock = PyThread_allocate_lock();
|
||||
if (new_lock == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* bpo-6721, bpo-40089: The old lock can be in an inconsistent state.
|
||||
fork() can be called in the middle of an operation on the lock done by
|
||||
another thread. So don't call PyThread_free_lock(*lock).
|
||||
|
||||
Leak memory on purpose. Don't release the memory either since the
|
||||
address of a mutex is relevant. Putting two mutexes at the same address
|
||||
can lead to problems. */
|
||||
|
||||
*lock = new_lock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue