[Python-checkins] gh-74953: Reformat PyThread_acquire_lock_timed() (#93947)

vstinner webhook-mailer at python.org
Sun Jun 19 05:50:25 EDT 2022


https://github.com/python/cpython/commit/2664d9aacf25aa18e1753e57f80f345ed9bd31e0
commit: 2664d9aacf25aa18e1753e57f80f345ed9bd31e0
branch: main
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2022-06-19T11:50:21+02:00
summary:

gh-74953: Reformat PyThread_acquire_lock_timed() (#93947)

Reformat the pthread implementation of PyThread_acquire_lock_timed()
using a mutex and a conditioinal variable.

* Add goto to avoid multiple indentation levels and exit quickly
* Use "while(1)" and make the control flow more obvious.
* PEP 7: Add braces around if blocks.

files:
M Python/thread_pthread.h

diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index 58b5999add388..a5719c39bc012 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -619,63 +619,79 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
 
     if (microseconds == 0) {
         status = pthread_mutex_trylock( &thelock->mut );
-        if (status != EBUSY)
+        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) {
-            struct timespec abs;
-            if (microseconds > 0) {
-                _PyThread_cond_after(microseconds, &abs);
+    if (status != 0) {
+        goto done;
+    }
+
+    if (thelock->locked == 0) {
+        success = PY_LOCK_ACQUIRED;
+        goto unlock;
+    }
+    if (microseconds == 0) {
+        goto unlock;
+    }
+
+    struct timespec abs;
+    if (microseconds > 0) {
+        _PyThread_cond_after(microseconds, &abs);
+    }
+    // Continue trying until we get the lock
+
+    // mut must be locked by me -- part of the condition protocol
+    while (1) {
+        if (microseconds > 0) {
+            status = pthread_cond_timedwait(&thelock->lock_released,
+                                            &thelock->mut, &abs);
+            if (status == 1) {
+                break;
             }
-            /* continue trying until we get the lock */
-
-            /* mut must be locked by me -- part of the condition
-             * protocol */
-            while (success == PY_LOCK_FAILURE) {
-                if (microseconds > 0) {
-                    status = pthread_cond_timedwait(
-                        &thelock->lock_released,
-                        &thelock->mut, &abs);
-                    if (status == 1) {
-                        break;
-                    }
-                    if (status == ETIMEDOUT)
-                        break;
-                    CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
-                }
-                else {
-                    status = pthread_cond_wait(
-                        &thelock->lock_released,
-                        &thelock->mut);
-                    CHECK_STATUS_PTHREAD("pthread_cond_wait");
-                }
-
-                if (intr_flag && status == 0 && thelock->locked) {
-                    /* We were woken up, but didn't get the lock.  We probably received
-                     * a signal.  Return PY_LOCK_INTR to allow the caller to handle
-                     * it and retry.  */
-                    success = PY_LOCK_INTR;
-                    break;
-                }
-                else if (status == 0 && !thelock->locked) {
-                    success = PY_LOCK_ACQUIRED;
-                }
+            if (status == ETIMEDOUT) {
+                break;
             }
+            CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
+        }
+        else {
+            status = pthread_cond_wait(
+                &thelock->lock_released,
+                &thelock->mut);
+            CHECK_STATUS_PTHREAD("pthread_cond_wait");
+        }
+
+        if (intr_flag && status == 0 && thelock->locked) {
+            // We were woken up, but didn't get the lock.  We probably received
+            // a signal.  Return PY_LOCK_INTR to allow the caller to handle
+            // it and retry.
+            success = PY_LOCK_INTR;
+            break;
+        }
+
+        if (status == 0 && !thelock->locked) {
+            success = PY_LOCK_ACQUIRED;
+            break;
         }
-        if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
-        status = pthread_mutex_unlock( &thelock->mut );
-        CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
+
+        // Wait got interrupted by a signal: retry
+    }
+
+unlock:
+    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;
+done:
+    if (error) {
+        success = PY_LOCK_FAILURE;
+    }
     return success;
 }
 



More information about the Python-checkins mailing list