summaryrefslogtreecommitdiffstats
path: root/Python/thread_pthread.h
diff options
context:
space:
mode:
authorAntoine Pitrou <pitrou@free.fr>2017-06-26 20:13:39 (GMT)
committerGitHub <noreply@github.com>2017-06-26 20:13:39 (GMT)
commit828488393ca79f2ceb0acc2d7c30fb68baad85f8 (patch)
treea39a997f59b8482e4f2c35e4749b287a5a00f9e5 /Python/thread_pthread.h
parent787826c9316b03ac8a197078ec1cdf98fa840c5c (diff)
downloadcpython-828488393ca79f2ceb0acc2d7c30fb68baad85f8.zip
cpython-828488393ca79f2ceb0acc2d7c30fb68baad85f8.tar.gz
cpython-828488393ca79f2ceb0acc2d7c30fb68baad85f8.tar.bz2
[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 f84ac420c2af98339678744953869cad3c253281) * Remove test undef
Diffstat (limited to 'Python/thread_pthread.h')
-rw-r--r--Python/thread_pthread.h46
1 files changed, 28 insertions, 18 deletions
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index c9ed796..79c66d4 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -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");
+ 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;
}
- 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));