Skip to content

Commit 2664d9a

Browse files
authored
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.
1 parent dba3fa5 commit 2664d9a

File tree

1 file changed

+62
-46
lines changed

1 file changed

+62
-46
lines changed

Python/thread_pthread.h

+62-46
Original file line numberDiff line numberDiff line change
@@ -619,63 +619,79 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
619619

620620
if (microseconds == 0) {
621621
status = pthread_mutex_trylock( &thelock->mut );
622-
if (status != EBUSY)
622+
if (status != EBUSY) {
623623
CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
624+
}
624625
}
625626
else {
626627
status = pthread_mutex_lock( &thelock->mut );
627628
CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
628629
}
629-
if (status == 0) {
630-
if (thelock->locked == 0) {
631-
success = PY_LOCK_ACQUIRED;
632-
}
633-
else if (microseconds != 0) {
634-
struct timespec abs;
635-
if (microseconds > 0) {
636-
_PyThread_cond_after(microseconds, &abs);
630+
if (status != 0) {
631+
goto done;
632+
}
633+
634+
if (thelock->locked == 0) {
635+
success = PY_LOCK_ACQUIRED;
636+
goto unlock;
637+
}
638+
if (microseconds == 0) {
639+
goto unlock;
640+
}
641+
642+
struct timespec abs;
643+
if (microseconds > 0) {
644+
_PyThread_cond_after(microseconds, &abs);
645+
}
646+
// Continue trying until we get the lock
647+
648+
// mut must be locked by me -- part of the condition protocol
649+
while (1) {
650+
if (microseconds > 0) {
651+
status = pthread_cond_timedwait(&thelock->lock_released,
652+
&thelock->mut, &abs);
653+
if (status == 1) {
654+
break;
637655
}
638-
/* continue trying until we get the lock */
639-
640-
/* mut must be locked by me -- part of the condition
641-
* protocol */
642-
while (success == PY_LOCK_FAILURE) {
643-
if (microseconds > 0) {
644-
status = pthread_cond_timedwait(
645-
&thelock->lock_released,
646-
&thelock->mut, &abs);
647-
if (status == 1) {
648-
break;
649-
}
650-
if (status == ETIMEDOUT)
651-
break;
652-
CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
653-
}
654-
else {
655-
status = pthread_cond_wait(
656-
&thelock->lock_released,
657-
&thelock->mut);
658-
CHECK_STATUS_PTHREAD("pthread_cond_wait");
659-
}
660-
661-
if (intr_flag && status == 0 && thelock->locked) {
662-
/* We were woken up, but didn't get the lock. We probably received
663-
* a signal. Return PY_LOCK_INTR to allow the caller to handle
664-
* it and retry. */
665-
success = PY_LOCK_INTR;
666-
break;
667-
}
668-
else if (status == 0 && !thelock->locked) {
669-
success = PY_LOCK_ACQUIRED;
670-
}
656+
if (status == ETIMEDOUT) {
657+
break;
671658
}
659+
CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
660+
}
661+
else {
662+
status = pthread_cond_wait(
663+
&thelock->lock_released,
664+
&thelock->mut);
665+
CHECK_STATUS_PTHREAD("pthread_cond_wait");
666+
}
667+
668+
if (intr_flag && status == 0 && thelock->locked) {
669+
// We were woken up, but didn't get the lock. We probably received
670+
// a signal. Return PY_LOCK_INTR to allow the caller to handle
671+
// it and retry.
672+
success = PY_LOCK_INTR;
673+
break;
674+
}
675+
676+
if (status == 0 && !thelock->locked) {
677+
success = PY_LOCK_ACQUIRED;
678+
break;
672679
}
673-
if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
674-
status = pthread_mutex_unlock( &thelock->mut );
675-
CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
680+
681+
// Wait got interrupted by a signal: retry
682+
}
683+
684+
unlock:
685+
if (success == PY_LOCK_ACQUIRED) {
686+
thelock->locked = 1;
676687
}
688+
status = pthread_mutex_unlock( &thelock->mut );
689+
CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
677690

678-
if (error) success = PY_LOCK_FAILURE;
691+
done:
692+
if (error) {
693+
success = PY_LOCK_FAILURE;
694+
}
679695
return success;
680696
}
681697

0 commit comments

Comments
 (0)