mirror of
https://github.com/python/cpython.git
synced 2025-09-29 11:45:57 +00:00
[3.6] bpo-30765: Avoid blocking when PyThread_acquire_lock() is asked not to (GH-2403) (#2418)
* bpo-30765: Avoid blocking when PyThread_acquire_lock() is asked not to lock
This is especially important if PyThread_acquire_lock() is called reentrantly
(for example from a signal handler).
* Update 2017-06-26-14-29-50.bpo-30765.Q5iBmf.rst
* Avoid core logic when taking the mutex failed
(cherry picked from commit f84ac420c2
)
This commit is contained in:
parent
64a0c266e7
commit
55ab604e3f
2 changed files with 50 additions and 43 deletions
|
@ -0,0 +1,2 @@
|
|||
Avoid blocking in pthread_mutex_lock() when PyThread_acquire_lock() is asked
|
||||
not to block.
|
|
@ -466,21 +466,27 @@ PyLockStatus
|
|||
PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
|
||||
int intr_flag)
|
||||
{
|
||||
PyLockStatus success;
|
||||
PyLockStatus success = PY_LOCK_FAILURE;
|
||||
pthread_lock *thelock = (pthread_lock *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
|
||||
lock, microseconds, intr_flag));
|
||||
|
||||
if (microseconds == 0) {
|
||||
status = pthread_mutex_trylock( &thelock->mut );
|
||||
if (status != EBUSY)
|
||||
CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
|
||||
}
|
||||
else {
|
||||
status = pthread_mutex_lock( &thelock->mut );
|
||||
CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
|
||||
|
||||
}
|
||||
if (status == 0) {
|
||||
if (thelock->locked == 0) {
|
||||
success = PY_LOCK_ACQUIRED;
|
||||
} else if (microseconds == 0) {
|
||||
success = PY_LOCK_FAILURE;
|
||||
} else {
|
||||
}
|
||||
else if (microseconds != 0) {
|
||||
struct timespec ts;
|
||||
if (microseconds > 0)
|
||||
MICROSECONDS_TO_TIMESPEC(microseconds, ts);
|
||||
|
@ -488,7 +494,6 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
|
|||
|
||||
/* mut must be locked by me -- part of the condition
|
||||
* protocol */
|
||||
success = PY_LOCK_FAILURE;
|
||||
while (success == PY_LOCK_FAILURE) {
|
||||
if (microseconds > 0) {
|
||||
status = pthread_cond_timedwait(
|
||||
|
@ -511,16 +516,16 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
|
|||
* it and retry. */
|
||||
success = PY_LOCK_INTR;
|
||||
break;
|
||||
} else if (status == 0 && !thelock->locked) {
|
||||
}
|
||||
else if (status == 0 && !thelock->locked) {
|
||||
success = PY_LOCK_ACQUIRED;
|
||||
} else {
|
||||
success = PY_LOCK_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
|
||||
status = pthread_mutex_unlock( &thelock->mut );
|
||||
CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
|
||||
}
|
||||
|
||||
if (error) success = PY_LOCK_FAILURE;
|
||||
dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue