diff options
author | Victor Stinner <vstinner@python.org> | 2020-04-07 23:11:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-07 23:11:49 +0200 |
commit | 87255be6964979b5abdc4b9dcf81cdcfdad6e753 (patch) | |
tree | 30f3c5a680dd7ed6435841ecd38166de7654503e /Python | |
parent | 48b069a003ba6c684a9ba78493fbbec5e89f10b8 (diff) | |
download | cpython-git-87255be6964979b5abdc4b9dcf81cdcfdad6e753.tar.gz |
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 'Python')
-rw-r--r-- | Python/thread_pthread.h | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 40e2e117a2..e3497e7d59 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -694,6 +694,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) { return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0); |