From 08e4b6acb7c26e77fd1b52b063838459207d1708 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 16 Dec 2011 05:27:15 +0000 Subject: [PATCH] * exceptions.cc (_cygtls::call_signal_handler): Fix debugging to not go to console. * fhandler.cc (fhandler_base_overlapped::wait_overlapped): Add temporary kludge to work around problem of make closing a handler while it is being read. * gendef (sigdelayed): Don't call a function if sig has been cleared. * sigproc.h (cygwait): Simplify slightly. --- winsup/cygwin/ChangeLog | 11 +++++++++++ winsup/cygwin/exceptions.cc | 2 +- winsup/cygwin/fhandler.cc | 32 +++++++++++++++++++------------- winsup/cygwin/gendef | 4 ++++ winsup/cygwin/sigproc.h | 9 +++------ 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a3e3ffc8a..b3c7c8842 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,14 @@ +2011-12-16 Christopher Faylor + + * exceptions.cc (_cygtls::call_signal_handler): Fix debugging to not go + to console. + * fhandler.cc (fhandler_base_overlapped::wait_overlapped): Add temporary + kludge to work around problem of make closing a handler while it is + being read. + * gendef (sigdelayed): Don't call a function if sig has been cleared. + + * sigproc.h (cygwait): Simplify slightly. + 2011-12-14 Corinna Vinschen * autoload.cc (GetSystemWow64DirectoryW): Define. diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 0ab89441b..9250b61f2 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1330,7 +1330,7 @@ _cygtls::call_signal_handler () _main_tls->lock (); if (_main_tls->sig && _main_tls->incyg) { - small_printf ("Redirecting to main_tls signal %d", _main_tls->sig); + paranoid_printf ("Redirecting to main_tls signal %d", _main_tls->sig); sig = _main_tls->sig; sa_flags = _main_tls->sa_flags; func = _main_tls->func; diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index c6388cc64..b6c719ccd 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1925,25 +1925,31 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte } if (res == overlapped_unknown) { - HANDLE h = writing ? get_output_handle () : get_handle (); DWORD wfres = cygwait (get_overlapped ()->hEvent); - /* Cancelling here to prevent races. It's possible that the I/O has - completed already, in which case this is a no-op. Otherwise, - WFMO returned because 1) This is a non-blocking call, 2) a signal - arrived, or 3) the operation was cancelled. These cases may be - overridden by the return of GetOverlappedResult which could detect - that I/O completion occurred. */ - CancelIo (h); - BOOL wores = GetOverlappedResult (h, get_overlapped (), bytes, false); - err = GetLastError (); - ResetEvent (get_overlapped ()->hEvent); /* Probably not needed but CYA */ - debug_printf ("wfres %d, wores %d, bytes %u", wfres, wores, *bytes); + HANDLE h = writing ? get_output_handle () : get_handle (); + BOOL wores; + if (wfres == WAIT_OBJECT_0 + 1 && !get_overlapped ()) + wores = 0; + else + { + /* Cancelling here to prevent races. It's possible that the I/O has + completed already, in which case this is a no-op. Otherwise, + WFMO returned because 1) This is a non-blocking call, 2) a signal + arrived, or 3) the operation was cancelled. These cases may be + overridden by the return of GetOverlappedResult which could detect + that I/O completion occurred. */ + CancelIo (h); + BOOL wores = GetOverlappedResult (h, get_overlapped (), bytes, false); + err = GetLastError (); + ResetEvent (get_overlapped ()->hEvent); /* Probably not needed but CYA */ + debug_printf ("wfres %d, wores %d, bytes %u", wfres, wores, *bytes); + } if (wores) res = overlapped_success; /* operation succeeded */ else if (wfres == WAIT_OBJECT_0 + 1) { err = ERROR_INVALID_AT_INTERRUPT_TIME; /* forces an EINTR below */ - debug_printf ("unhandled signal"); + debug_printf ("signal"); res = overlapped_error; } else if (nonblocking) diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index 0cd27341f..d20138ff7 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -221,6 +221,10 @@ _sigdelayed: call _yield jmp 1b 2: incl $tls::incyg(%ebx) + movl $tls::sig(%ebx),%eax + testl %eax,%eax + jz 4f # call_signal_handler may have beat us + # to it pushl $tls::saved_errno(%ebx) # saved errno call _set_process_mask_delta pushl %eax diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index f5547154d..a9678376e 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -87,14 +87,11 @@ cygwait (HANDLE h, DWORD howlong = INFINITE) HANDLE w4[3]; DWORD n = 0; DWORD wait_signal; - if ((w4[n] = h) == NULL) + if ((w4[n] = h) != NULL) + wait_signal = WAIT_OBJECT_0 + ++n; + else wait_signal = WAIT_OBJECT_0 + 15; /* Arbitrary. Don't call signal handler if only waiting for signal */ - else - { - n++; - wait_signal = n; - } w4[n++] = signal_arrived; if ((w4[n] = pthread::get_cancel_event ()) != NULL) n++;