diff options
author | Christopher Faylor <me@cgf.cx> | 2011-12-14 00:06:31 +0400 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2011-12-14 00:06:31 +0400 |
commit | 45d7b637fa74ac79469892653188e2554f151633 (patch) | |
tree | 1a23cbc08e233079ef13732fc7f36525befa2938 /winsup/cygwin/select.cc | |
parent | 8d1bda71b4538fe0c4dee14f057645da33443a9e (diff) |
* dcrt0.cc (init_windows_system_directory): Record system_wow64_directory
information.
* exceptions.cc (_cygtls::inside_kernel): Modernize comment. Consider
executing a DLL from the Wow64 directory as being "in the kernel".
(_cygtls::call_signal_handler): For now, only deal with main_tls signals if
main_tls is known to be executing in the cygwin DLL. To more closely emulate
linux, consider the operation to be restartable if not executing in the main
thread.
* globals.cc (windows_system_directory): Remove NO_COPY.
(windows_system_directory_length): Ditto.
(system_wow64_directory): New variable.
(system_wow64_directory_length): Ditto.
* select.cc (cygwin_select): Don't issue a EINTR on non-main threads since that
seems to be what Linux does. Add missing break to signal case/switch.
(select_stuff::wait): Don't issue a EINTR on non-main threads since that seems
to be what Linux does. Remove now-unneeded accommodation for
WAIT_IO_COMPLETION. Add a comment.
* sigproc.h (cygwait): Ditto. Don't return if signal_received noticed and it's
not the main thread.
* signal.cc (sigprocmask): Add standard syscall debug stuff.
* thread.cc (pthread_sigmask): Ditto.
Diffstat (limited to 'winsup/cygwin/select.cc')
-rw-r--r-- | winsup/cygwin/select.cc | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 77a78c427..5e6baa6f5 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -129,23 +129,28 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fd_set *w = allocfd_set (maxfds); fd_set *e = allocfd_set (maxfds); - int res = 1; + int res = 0; /* Degenerate case. No fds to wait for. Just wait. */ if (sel.start.next == NULL) - switch (cygwait (ms)) - { - case WAIT_OBJECT_0: - select_printf ("signal received"); - set_sig_errno (EINTR); - res = -1; - case WAIT_OBJECT_0 + 1: - sel.destroy (); - pthread::static_cancel_self (); - /*NOTREACHED*/ - default: - res = 1; - break; - } + while (!res) + switch (cygwait (ms)) + { + case WAIT_OBJECT_0: + _my_tls.call_signal_handler (); + if (&_my_tls != _main_tls) + continue; /* Emulate linux behavior */ + select_printf ("signal received"); + set_sig_errno (EINTR); + res = -1; + break; + case WAIT_OBJECT_0 + 1: + sel.destroy (); + pthread::static_cancel_self (); + /*NOTREACHED*/ + default: + res = 1; /* temporary flag. Will be set to zero below. */ + break; + } else if (sel.always_ready || ms == 0) res = 0; else @@ -321,12 +326,11 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, MWMO_INPUTAVAILABLE); switch (wait_ret) - { - case WAIT_IO_COMPLETION: - syscall_printf ("woke due to apc"); - continue; /* Keep going */ - break; + { case WAIT_OBJECT_0: + _my_tls.call_signal_handler (); + if (&_my_tls != _main_tls) + continue; /* Emulate linux behavior */ cleanup (); select_printf ("signal received"); set_sig_errno (EINTR); @@ -338,6 +342,8 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, destroy (); pthread::static_cancel_self (); } + /* This wasn't a cancel event. It was just a normal object to wait + for. */ break; case WAIT_FAILED: cleanup (); @@ -350,7 +356,7 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, select_printf ("timed out"); res = 1; goto out; - } + } select_printf ("woke up. wait_ret %d. verifying", wait_ret); s = &start; |