diff options
author | mpage <mpage@meta.com> | 2024-03-01 21:43:12 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-01 21:43:12 (GMT) |
commit | 9e88173d363fb22c2c7bf3da3a266817db6bf24b (patch) | |
tree | dec22e7ab1b7d7815490b8a3fecbe68392ad42e4 /Python/lock.c | |
parent | 5e0c7bc1d311048e8252bae6fc91cb51c556f807 (diff) | |
download | cpython-9e88173d363fb22c2c7bf3da3a266817db6bf24b.zip cpython-9e88173d363fb22c2c7bf3da3a266817db6bf24b.tar.gz cpython-9e88173d363fb22c2c7bf3da3a266817db6bf24b.tar.bz2 |
gh-114271: Make `_thread.ThreadHandle` thread-safe in free-threaded builds (GH-115190)
Make `_thread.ThreadHandle` thread-safe in free-threaded builds
We protect the mutable state of `ThreadHandle` using a `_PyOnceFlag`.
Concurrent operations (i.e. `join` or `detach`) on `ThreadHandle` block
until it is their turn to execute or an earlier operation succeeds.
Once an operation has been applied successfully all future operations
complete immediately.
The `join()` method is now idempotent. It may be called multiple times
but the underlying OS thread will only be joined once. After `join()`
succeeds, any future calls to `join()` will succeed immediately.
The internal thread handle `detach()` method has been removed.
Diffstat (limited to 'Python/lock.c')
-rw-r--r-- | Python/lock.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/Python/lock.c b/Python/lock.c index 5fa8bf7..de25adc 100644 --- a/Python/lock.c +++ b/Python/lock.c @@ -249,6 +249,13 @@ _PyRawMutex_UnlockSlow(_PyRawMutex *m) } } +int +_PyEvent_IsSet(PyEvent *evt) +{ + uint8_t v = _Py_atomic_load_uint8(&evt->v); + return v == _Py_LOCKED; +} + void _PyEvent_Notify(PyEvent *evt) { @@ -297,6 +304,30 @@ PyEvent_WaitTimed(PyEvent *evt, PyTime_t timeout_ns) } } +_PyEventRc * +_PyEventRc_New(void) +{ + _PyEventRc *erc = (_PyEventRc *)PyMem_RawCalloc(1, sizeof(_PyEventRc)); + if (erc != NULL) { + erc->refcount = 1; + } + return erc; +} + +void +_PyEventRc_Incref(_PyEventRc *erc) +{ + _Py_atomic_add_ssize(&erc->refcount, 1); +} + +void +_PyEventRc_Decref(_PyEventRc *erc) +{ + if (_Py_atomic_add_ssize(&erc->refcount, -1) == 1) { + PyMem_RawFree(erc); + } +} + static int unlock_once(_PyOnceFlag *o, int res) { |