gh-134745: Change PyThread_allocate_lock() implementation to PyMutex (#134747)

Co-authored-by: Sam Gross <colesbury@gmail.com>
This commit is contained in:
Victor Stinner 2025-05-30 12:15:47 +02:00 committed by GitHub
parent 45c6c48afc
commit ebf6d13567
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 86 additions and 491 deletions

View file

@ -39,7 +39,8 @@
const long long PY_TIMEOUT_MAX = PY_TIMEOUT_MAX_VALUE;
static void PyThread__init_thread(void); /* Forward */
/* Forward declaration */
static void PyThread__init_thread(void);
#define initialized _PyRuntime.threads.initialized
@ -71,6 +72,79 @@ PyThread_init_thread(void)
#endif
/*
* Lock support.
*/
PyThread_type_lock
PyThread_allocate_lock(void)
{
if (!initialized) {
PyThread_init_thread();
}
PyMutex *lock = (PyMutex *)PyMem_RawMalloc(sizeof(PyMutex));
if (lock) {
*lock = (PyMutex){0};
}
return (PyThread_type_lock)lock;
}
void
PyThread_free_lock(PyThread_type_lock lock)
{
PyMem_RawFree(lock);
}
PyLockStatus
PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
int intr_flag)
{
PyTime_t timeout; // relative timeout
if (microseconds >= 0) {
// bpo-41710: PyThread_acquire_lock_timed() cannot report timeout
// overflow to the caller, so clamp the timeout to
// [PyTime_MIN, PyTime_MAX].
//
// PyTime_MAX nanoseconds is around 292.3 years.
//
// _thread.Lock.acquire() and _thread.RLock.acquire() raise an
// OverflowError if microseconds is greater than PY_TIMEOUT_MAX.
timeout = _PyTime_FromMicrosecondsClamp(microseconds);
}
else {
timeout = -1;
}
_PyLockFlags flags = _Py_LOCK_DONT_DETACH;
if (intr_flag) {
flags |= _PY_FAIL_IF_INTERRUPTED;
}
return _PyMutex_LockTimed((PyMutex *)lock, timeout, flags);
}
void
PyThread_release_lock(PyThread_type_lock lock)
{
PyMutex_Unlock((PyMutex *)lock);
}
int
_PyThread_at_fork_reinit(PyThread_type_lock *lock)
{
_PyMutex_at_fork_reinit((PyMutex *)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);
}
/* return the current thread stack size */
size_t
PyThread_get_stacksize(void)
@ -261,11 +335,7 @@ PyThread_GetInfo(void)
#ifdef HAVE_PTHREAD_STUBS
value = Py_NewRef(Py_None);
#elif defined(_POSIX_THREADS)
#ifdef USE_SEMAPHORES
value = PyUnicode_FromString("semaphore");
#else
value = PyUnicode_FromString("mutex+cond");
#endif
value = PyUnicode_FromString("pymutex");
if (value == NULL) {
Py_DECREF(threadinfo);
return NULL;