From 477a593693076ce252ee463c4d06a9fa12a00d02 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 6 Sep 2021 14:35:05 +0200 Subject: [PATCH] Cygwin: pipes: cancel async IO if thread cancellation is in progress Just cancelling a thread doesn't cancel async IO started by this thread. Fix this by returning from cygwait and calling CancelIo before canceling self. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_pipe.cc | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc index fe0bf0ca2..76ce895e2 100644 --- a/winsup/cygwin/fhandler_pipe.cc +++ b/winsup/cygwin/fhandler_pipe.cc @@ -292,12 +292,15 @@ fhandler_pipe::raw_read (void *ptr, size_t& len) len1, NULL, NULL); if (evt && status == STATUS_PENDING) { - waitret = cygwait (evt); + waitret = cygwait (evt, INFINITE, cw_cancel | cw_sig); if (waitret == WAIT_OBJECT_0) status = io.Status; } if (waitret == WAIT_CANCELED) - status = STATUS_THREAD_CANCELED; + { + status = STATUS_THREAD_CANCELED; + break; + } else if (waitret == WAIT_SIGNALED) status = STATUS_THREAD_SIGNALED; else if (isclosed ()) /* A signal handler might have closed the fd. */ @@ -360,7 +363,10 @@ fhandler_pipe::raw_read (void *ptr, size_t& len) nbytes = (size_t) -1; } else if (status == STATUS_THREAD_CANCELED) - pthread::static_cancel_self (); + { + CancelIo (get_handle ()); + pthread::static_cancel_self (); + } len = nbytes; } @@ -436,12 +442,15 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len) } if (evt && status == STATUS_PENDING) { - waitret = cygwait (evt); + waitret = cygwait (evt, INFINITE, cw_cancel | cw_sig); if (waitret == WAIT_OBJECT_0) status = io.Status; } if (waitret == WAIT_CANCELED) - status = STATUS_THREAD_CANCELED; + { + status = STATUS_THREAD_CANCELED; + break; + } else if (waitret == WAIT_SIGNALED) status = STATUS_THREAD_SIGNALED; else if (isclosed ()) /* A signal handler might have closed the fd. */ @@ -476,7 +485,10 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len) if (status == STATUS_THREAD_SIGNALED && nbytes == 0) set_errno (EINTR); else if (status == STATUS_THREAD_CANCELED) - pthread::static_cancel_self (); + { + CancelIo (get_handle ()); + pthread::static_cancel_self (); + } return nbytes ?: -1; }