[2.7] bpo-30765: Avoid blocking when PyThread_acquire_lock() is asked not to (GH-2403) (#2420)
* [2.7] bpo-30765: Avoid blocking when PyThread_acquire_lock() is asked not to (GH-2403)
* 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
)
* Remove test undef
This commit is contained in:
parent
787826c931
commit
828488393c
|
@ -0,0 +1,2 @@
|
|||
Avoid blocking in pthread_mutex_lock() when PyThread_acquire_lock() is asked
|
||||
not to block.
|
|
@ -410,31 +410,41 @@ PyThread_free_lock(PyThread_type_lock lock)
|
|||
int
|
||||
PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int success;
|
||||
int success = 0;
|
||||
pthread_lock *thelock = (pthread_lock *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
|
||||
status = pthread_mutex_lock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_lock[1]");
|
||||
success = thelock->locked == 0;
|
||||
|
||||
if ( !success && waitflag ) {
|
||||
/* continue trying until we get the lock */
|
||||
|
||||
/* mut must be locked by me -- part of the condition
|
||||
* protocol */
|
||||
while ( thelock->locked ) {
|
||||
status = pthread_cond_wait(&thelock->lock_released,
|
||||
&thelock->mut);
|
||||
CHECK_STATUS("pthread_cond_wait");
|
||||
}
|
||||
success = 1;
|
||||
if (waitflag) {
|
||||
status = pthread_mutex_lock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_lock[1]");
|
||||
}
|
||||
else {
|
||||
status = pthread_mutex_trylock( &thelock->mut );
|
||||
if (status != EBUSY)
|
||||
CHECK_STATUS("pthread_mutex_trylock[1]");
|
||||
}
|
||||
if (status == 0) {
|
||||
success = thelock->locked == 0;
|
||||
|
||||
if ( !success && waitflag ) {
|
||||
/* continue trying until we get the lock */
|
||||
|
||||
/* mut must be locked by me -- part of the condition
|
||||
* protocol */
|
||||
while ( thelock->locked ) {
|
||||
status = pthread_cond_wait(&thelock->lock_released,
|
||||
&thelock->mut);
|
||||
CHECK_STATUS("pthread_cond_wait");
|
||||
}
|
||||
success = 1;
|
||||
}
|
||||
|
||||
if (success) thelock->locked = 1;
|
||||
status = pthread_mutex_unlock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_unlock[1]");
|
||||
}
|
||||
if (success) thelock->locked = 1;
|
||||
status = pthread_mutex_unlock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_unlock[1]");
|
||||
|
||||
if (error) success = 0;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
|
|
Loading…
Reference in New Issue