From ee2984326b89e0a38598c0bdf0aa7c76d865c9ed Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 29 Jul 2007 05:22:05 +0000 Subject: [PATCH] * cygtls.h (_cygtls::inside_kernel): Move function declaration into _cygtls class. * exceptions.cc (_cygtls::inside_kernel): Move function definition into _cygtls class. * fhandler.cc (fhandler_base::wait_overlapped): Make return tri-state to detect when there is a EINTR situation. Add a pointer to a length parameter. Move GetOverlappedResult into this function. (fhandler_base::read_overlapped): Accommodate above changes and loop if we receive a restartable signal. (fhandler_base::write_overlapped): Ditto. * fhandler.h (fhandler_base::wait_overlapped): Reflect above changes. * fhandler_fifo.cc (fhandler_fifo::wait): Ditto. --- winsup/cygwin/ChangeLog | 16 ++++++++++ winsup/cygwin/cygtls.h | 3 +- winsup/cygwin/exceptions.cc | 8 ++--- winsup/cygwin/fhandler.cc | 53 ++++++++++++++++++++++++---------- winsup/cygwin/fhandler.h | 2 +- winsup/cygwin/fhandler_fifo.cc | 2 +- 6 files changed, 61 insertions(+), 23 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 6f8e623b9..0ef56eb56 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2007-07-29 Christopher Faylor + + * cygtls.h (_cygtls::inside_kernel): Move function declaration into + _cygtls class. + * exceptions.cc (_cygtls::inside_kernel): Move function definition into + _cygtls class. + + * fhandler.cc (fhandler_base::wait_overlapped): Make return tri-state + to detect when there is a EINTR situation. Add a pointer to a length + parameter. Move GetOverlappedResult into this function. + (fhandler_base::read_overlapped): Accommodate above changes and loop if + we receive a restartable signal. + (fhandler_base::write_overlapped): Ditto. + * fhandler.h (fhandler_base::wait_overlapped): Reflect above changes. + * fhandler_fifo.cc (fhandler_fifo::wait): Ditto. + 2007-07-28 Corinna Vinschen * ntdll.h (RtlEqualUnicodePathPrefix): Rename from RtlEqualPathPrefix. diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index d42ccc6f7..7e584f6fc 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -190,7 +190,8 @@ struct _cygtls /* exception handling */ static int handle_exceptions (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *); - static int handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *c, void *); + static int handle_threadlist_exception (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *); + bool inside_kernel (CONTEXT *); void init_exception_handler (int (*) (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void*)); void init_threadlist_exceptions (); void signal_exit (int) __attribute__ ((noreturn, regparm(2))); diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index efb7a5448..648a39f43 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -282,13 +282,13 @@ stackdump (DWORD ebp, int open_file, bool isexception) i == 16 ? " (more stack frames may be present)" : ""); } -static bool -inside_kernel (CONTEXT *cx) +bool +_cygtls::inside_kernel (CONTEXT *cx) { int res; MEMORY_BASIC_INFORMATION m; - if (!_my_tls.isinitialized ()) + if (!isinitialized ()) return true; memset (&m, 0, sizeof m); @@ -627,7 +627,7 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT error_code |= 1; if (e->ExceptionInformation[0]) /* Write access */ error_code |= 2; - if (!inside_kernel (in)) /* User space */ + if (!me.inside_kernel (in)) /* User space */ error_code |= 4; klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d", __progname, myself->pid, diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index ac9527ad8..efe2aa665 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1694,9 +1694,11 @@ fhandler_base::destroy_overlapped () } } -bool -fhandler_base::wait_overlapped (bool& res, bool writing) +int +fhandler_base::wait_overlapped (bool& res, bool writing, DWORD *bytes) { + if (bytes) + *bytes = (DWORD) -1; if (!res && GetLastError () != ERROR_IO_PENDING) __seterrno (); else @@ -1712,15 +1714,27 @@ fhandler_base::wait_overlapped (bool& res, bool writing) w4[0] = get_overlapped ()->hEvent; if (&_my_tls == _main_tls) w4[n++] = signal_arrived; + HANDLE h = writing ? get_output_handle () : get_handle (); switch (WaitForMultipleObjects (n, w4, false, INFINITE)) { case WAIT_OBJECT_0: - res = true; + if (!bytes || + GetOverlappedResult (h, get_overlapped (), bytes, false)) + res = 1; + else + { + __seterrno (); + res = -1; + } break; case WAIT_OBJECT_0 + 1: - CancelIo (writing ? get_output_handle () : get_handle ()); + CancelIo (h); set_errno (EINTR); - res = false; + res = 0; + break; + default: + __seterrno (); + res = -1; break; } } @@ -1735,11 +1749,14 @@ fhandler_base::read_overlapped (void *ptr, size_t& len) assert (get_overlapped ()); assert (get_overlapped ()->hEvent); #endif - bool res = ReadFile (get_handle (), ptr, len, (DWORD *) &len, - get_overlapped ()); - if (!wait_overlapped (res, false) - || !GetOverlappedResult (get_handle (), get_overlapped (), (DWORD *) &len, false)) - len = 0; + while (1) + { + bool res = ReadFile (get_handle (), ptr, len, (DWORD *) &len, + get_overlapped ()); + int wres = wait_overlapped (res, false, (DWORD *) &len); + if (wres || !_my_tls.call_signal_handler ()) + break; + } } int @@ -1747,11 +1764,15 @@ fhandler_base::write_overlapped (const void *ptr, size_t len) { DWORD bytes_written; - bool res = WriteFile (get_output_handle (), ptr, len, &bytes_written, - get_overlapped ()); - if (!wait_overlapped (res, true) - || !GetOverlappedResult (get_handle (), get_overlapped (), - &bytes_written, false)) - return -1; + while (1) + { + bool res = WriteFile (get_output_handle (), ptr, len, &bytes_written, + get_overlapped ()); + int wres = wait_overlapped (res, true, &bytes_written); + if (wres < 0) + return -1; + if (wres || !_my_tls.call_signal_handler ()) + break; + } return bytes_written; } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index af505e8c4..9a91191f9 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -139,7 +139,7 @@ class fhandler_base DWORD fs_flags; HANDLE read_state; path_conv pc; - bool wait_overlapped (bool&, bool) __attribute__ ((regparm (2))); + int wait_overlapped (bool&, bool, DWORD *) __attribute__ ((regparm (3))); bool setup_overlapped () __attribute__ ((regparm (1))); void destroy_overlapped () __attribute__ ((regparm (1))); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index ec1bbf24f..668c4e2f7 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -139,7 +139,7 @@ fhandler_fifo::wait (bool iswrite) bool res = ConnectNamedPipe (get_handle (), get_overlapped ()); if (res || GetLastError () == ERROR_PIPE_CONNECTED) return true; - return wait_overlapped (res, iswrite); + return wait_overlapped (res, iswrite, NULL); default: break; }