]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-114271: Make `_thread.lock` thread-safe in free-threaded builds (#116433)
authormpage <mpage@meta.com>
Wed, 6 Mar 2024 20:46:36 +0000 (12:46 -0800)
committerGitHub <noreply@github.com>
Wed, 6 Mar 2024 20:46:36 +0000 (15:46 -0500)
Previously, the `locked` field was set after releasing the lock. This reverses
the order so that the `locked` field is set while the lock is still held.

There is still one thread-safety issue where `locked` is checked prior to
releasing the lock, however, in practice that will only be an issue when
unlocking the lock is contended, which should be rare.

Modules/_threadmodule.c

index 3a8f77d6dfbbc6a9c4410db6f780f4b7f1f2a64b..7587ac00eef60c26d3cea5fa4ae79c6cd3f64dcb 100644 (file)
@@ -390,8 +390,8 @@ lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
         return NULL;
     }
 
-    PyThread_release_lock(self->lock_lock);
     self->locked = 0;
+    PyThread_release_lock(self->lock_lock);
     Py_RETURN_NONE;
 }
 
@@ -1665,8 +1665,8 @@ release_sentinel(void *weakref_raw)
     lockobject *lock = (lockobject *)_PyWeakref_GET_REF(weakref);
     if (lock != NULL) {
         if (lock->locked) {
-            PyThread_release_lock(lock->lock_lock);
             lock->locked = 0;
+            PyThread_release_lock(lock->lock_lock);
         }
         Py_DECREF(lock);
     }