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

Lines changed: 62 additions & 46 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy