public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
From: Corinna Vinschen <corinna-cygwin@cygwin.com>
To: cygwin-patches@cygwin.com
Subject: Re: [PATCH 08/11] Cygwin: testsuite: Busy-wait in cancel3 and cancel5
Date: Tue, 18 Jul 2023 14:09:30 +0200	[thread overview]
Message-ID: <ZLaA+toDV1ms4Ene@calimero.vinschen.de> (raw)
In-Reply-To: <a3513077-38c4-0839-1bfd-73f331069454@dronecode.org.uk>

On Jul 18 12:20, Jon Turney wrote:
> On 17/07/2023 16:41, Corinna Vinschen wrote:
> > > Looking into pthread::cancel we have this order of things:
> > > 
> > >      // cancel deferred
> > >      mutex.unlock ();
> > >      canceled = true;
> > >      SetEvent (cancel_event);
> > >      return 0;
> > > 
> > > The canceled var is set before the SetEvent call.
> > > What if the thread is terminated after canceled is set to true but
> > > before SetEvent is called?
> > > 
> > > pthread::testcancel claims:
> > > 
> > >    We check for the canceled flag first. [...]
> > >    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.
> > > 
> > > Neat idea to speed up the code, but doesn't that mean we have a
> > > potential deadlock, especially given that pthread::testcancel calls WFSO
> > > with an INFINITE timeout?
> 
> I'm not sure I follow: another thread sets cancelled = true, just before we
> hit pthread::testcancel(), so we go into the WFSO, but then the other thread
> continues, signals cancel_event and everything's fine.
> 
> What meaning are you assigning to "interrupted" here?
> 
> Are we worried about the thread calling pthread_cancel being cancelled
> itself?

Yes.  My concern is if the thread gets terminated between setting
canceled and setting the event object.

Prior to commit 42faed412857, we didn't wait infinitely, just tested the
event object.  Only with adding the canceled variable, we (better: I)
added the the infinite timeout.

I don't see a real reason to do that.  I think this should be changed
to just checking the event object, see the below patch.

> > > And if so, how do we fix this?  Theoretically, the most simple
> > > solution might be to call SetEvent before setting the canceled
> > > variable, but in fact we would have to make setting canceld
> > > and cancel_event an atomic operation.
> 
> Well, yeah, that is required for them to be coherent. But we have a mutex on
> the thread object for that purpose, and I don't quite see why it's released
> so early here.

The mutex is not guarding canceled or the event object.  Thus it's not
used in testcancel either, otherwise introducing the canceled var to
speed up stuff wouldn't have made any sense.


Corinna


commit 518e5e46f064de41d3ef6d6ef743e2e760a46282
Author:     Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Mon Jul 17 18:02:04 2023 +0200
Commit:     Corinna Vinschen <corinna@vinschen.de>
CommitDate: Tue Jul 18 10:11:30 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 <corinna@vinschen.de>

diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index f614e01c42f6..21e89e146e0a 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -961,12 +961,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.

  reply	other threads:[~2023-07-18 12:09 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-13 11:38 [PATCH 00/11] More testsuite fixes Jon Turney
2023-07-13 11:38 ` [PATCH 01/11] Cygwin: testsuite: Setup test prereqs in 'installation' the tests run in Jon Turney
2023-07-13 11:38 ` [PATCH 02/11] Cygwin: testsuite: Add a simple timeout mechanism Jon Turney
2023-07-13 11:38 ` [PATCH 03/11] Cygwin: testsuite: Remove const from writable string in fcntl07b Jon Turney
2023-07-13 11:38 ` [PATCH 04/11] Cygwin: testsuite: Skip devdsp test when no audio devices present Jon Turney
2023-07-13 11:38 ` [PATCH 05/11] Cygwin: testsuite: Just log result of second open of /dev/dsp Jon Turney
2023-07-13 11:38 ` [PATCH 06/11] Cygwin: testsuite: Also check direct call in systemcall Jon Turney
2023-07-13 11:39 ` [PATCH 07/11] Cygwin: testsuite: Fix for limited thread priority values Jon Turney
2023-07-13 11:39 ` [PATCH 08/11] Cygwin: testsuite: Busy-wait in cancel3 and cancel5 Jon Turney
2023-07-13 11:43   ` Jon Turney
2023-07-13 18:16   ` Corinna Vinschen
2023-07-13 18:37     ` Corinna Vinschen
2023-07-13 18:53       ` Corinna Vinschen
2023-07-14 13:04         ` Jon Turney
2023-07-14 18:57           ` Corinna Vinschen
2023-07-17 11:05             ` Corinna Vinschen
2023-07-17 11:51               ` Jon Turney
2023-07-17 14:21                 ` Corinna Vinschen
2023-07-17 15:41                   ` Corinna Vinschen
2023-07-17 18:23                     ` Corinna Vinschen
2023-07-18 11:20                     ` Jon Turney
2023-07-18 12:09                       ` Corinna Vinschen [this message]
2023-07-18 15:52                         ` Jon Turney
2023-07-17 11:51           ` Jon Turney
2023-07-17 14:04             ` Corinna Vinschen
2023-07-17 14:22               ` Corinna Vinschen
2023-07-13 11:39 ` [PATCH 09/11] Cygwin: testsuite: Fix a buffer overflow in symlink01 Jon Turney
2023-07-13 18:17   ` Corinna Vinschen
2023-07-14 13:04     ` Jon Turney
2023-07-13 11:39 ` [PATCH 10/11] Cygwin: testsuite: Minor fixes to umask03 Jon Turney
2023-07-13 18:18   ` Corinna Vinschen
2023-07-13 11:39 ` [PATCH 11/11] Cygwin: testsuite: Drop Adminstrator privileges while running tests Jon Turney
2023-07-13 18:05 ` [PATCH 00/11] More testsuite fixes Corinna Vinschen
2023-07-17 11:58 ` Jon Turney
2023-07-17 14:02   ` Corinna Vinschen
2023-07-18 13:37     ` Jon Turney
2023-07-18 14:52       ` Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZLaA+toDV1ms4Ene@calimero.vinschen.de \
    --to=corinna-cygwin@cygwin.com \
    --cc=cygwin-patches@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).