gh-114271: Make _thread.lock thread-safe in free-threaded builds (#116433)

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.
This commit is contained in:
mpage 2024-03-06 12:46:36 -08:00 committed by GitHub
parent ce0ae1d784
commit c62144a02c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View 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);
}