summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-06-19 09:50:21 (GMT)
committerGitHub <noreply@github.com>2022-06-19 09:50:21 (GMT)
commit2664d9aacf25aa18e1753e57f80f345ed9bd31e0 (patch)
tree6e976fb6478eb26a7ca695ae4331ed334ed39e82 /Python
parentdba3fa57e26c5b0f7a4bfd3228a9bc109f35b6c8 (diff)
downloadcpython-2664d9aacf25aa18e1753e57f80f345ed9bd31e0.zip
cpython-2664d9aacf25aa18e1753e57f80f345ed9bd31e0.tar.gz
cpython-2664d9aacf25aa18e1753e57f80f345ed9bd31e0.tar.bz2
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.
Diffstat (limited to 'Python')
-rw-r--r--Python/thread_pthread.h108
1 files changed, 62 insertions, 46 deletions
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index 58b5999..a5719c3 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;
}