https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=a02144808c5bc4e9753bfeabf06313c6413e1cd3
commit a02144808c5bc4e9753bfeabf06313c6413e1cd3 Author: Corinna Vinschen <[email protected]> AuthorDate: Mon Jul 17 18:02:04 2023 +0200 Commit: Corinna Vinschen <[email protected]> CommitDate: Tue Jul 18 22:21:36 2023 +0200 Cygwin: don't wait infinitely on a pthread cancel event Starting with commit 42faed412857 ("* thread.h (class pthread): Add bool member canceled."), pthread::testcancel waits infinitely on cancel_event after it checked if the canceled variable is set. However, this might introduce a deadlock, if the thread calling pthread_cancel is terminated after setting canceled to true, but before calling SetEvent on cancel_event. In fact, it's not at all necessary to wait infinitely. By definition, the thread is only canceled if cancel_event is set. The canceled variable is just a helper to speed up code. We can safely assume that the thread hasn't been canceled yet, if canceled is set, but cancel_event isn't. Fixes: 42faed412857 ("* thread.h (class pthread): Add bool member canceled.") Signed-off-by: Corinna Vinschen <[email protected]> Diff: --- winsup/cygwin/thread.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index afddf42821ad..7bb4f9fc8341 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -962,12 +962,9 @@ pthread::testcancel () pthread_testcancel function a lot without adding the overhead of an OS call. Only if the thread is marked as canceled, we wait for cancel_event being really set, on the off-chance that pthread_cancel - gets interrupted before calling SetEvent. */ - if (canceled) - { - WaitForSingleObject (cancel_event, INFINITE); - cancel_self (); - } + gets interrupted or terminated before calling SetEvent. */ + if (canceled && IsEventSignalled (cancel_event)) + cancel_self (); } /* Return cancel event handle if it exists *and* cancel is not disabled.
