diff options
author | Christopher Faylor <me@cgf.cx> | 2001-11-01 21:15:53 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2001-11-01 21:15:53 +0000 |
commit | 1229d4f4eeec60957897cbf851adff5f61ab4df5 (patch) | |
tree | 070d8a75c184f67cf5aaade88b4903aa8d2743cb /winsup/cygwin/select.cc | |
parent | 5cf6708ef4559248ba751adc349af475e654be2a (diff) | |
download | cygnal-1229d4f4eeec60957897cbf851adff5f61ab4df5.tar.gz cygnal-1229d4f4eeec60957897cbf851adff5f61ab4df5.tar.bz2 cygnal-1229d4f4eeec60957897cbf851adff5f61ab4df5.zip |
* dtable.cc (dtable::build_fhandler): Issue internal error on unknown device.
* fhandler.cc (fhandler_base::close): Show both name and handle in debugging
output.
* fhandler.h (fhandler_base::get_guard): New virtual method.
(fhandler_pipe::get_guard): New method.
(fhandler_socket::ready_for_read): Delete declaration.
(fhandler_pipe::ready_for_read): Ditto.
(fhandler_serial::ready_for_read): Ditto.
(fhandler_console::ready_for_read): Ditto.
(fhandler_tty_common::ready_for_read): Ditto.
(fhandler_windows::ready_for_read): Ditto.
(struct select_record::peek): Declare new method.
* select.cc (MAKEready): Delete.
(peek_pipe): Use get_guard method to retrieve potential guard mutex handle.
(fhandler_base::ready_for_read): Rewrite as generic ready-for-read handler.
Should only be called for "slow" devices.
(fhandler_socket::ready_for_read): Delete definition.
(fhandler_pipe::ready_for_read): Ditto.
(fhandler_serial::ready_for_read): Ditto.
(fhandler_console::ready_for_read): Ditto.
(fhandler_tty_common::ready_for_read): Ditto.
(fhandler_windows::ready_for_read): Ditto.
(fhandler_pipe::select_read): Fill in new peek record in select_record
structure.
(fhandler_console::select_read): Ditto.
(fhandler_tty_common::select_read): Ditto.
(fhandler_serial::select_read): Ditto.
(fhandler_socket::select_read): Ditto.
(fhandler_socket::select_read): Ditto.
(fhandler_tty_slave::ready_for_read): Check for tty not open. Set errnos
appropriately.
* syscalls.cc (_read): Allow ready_for_read to set errno.
* pinfo.cc (pinfo::init): Return spawn/NO_WAIT process as valid if it is
initializing.
* sigproc.cc (getsem): Adjust wait for process to initialize downward to avoid
huge waits.
Diffstat (limited to 'winsup/cygwin/select.cc')
-rw-r--r-- | winsup/cygwin/select.cc | 114 |
1 files changed, 53 insertions, 61 deletions
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 489bca5cc..2b807e388 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -84,24 +84,6 @@ typedef long fd_mask; #define allocfd_set(n) ((fd_set *) memset (alloca (sizeof_fd_set (n)), 0, sizeof_fd_set (n))) #define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n)); -/* Make a fhandler_foo::ready_for_ready method. - Assumption: The "ready_for_read" methods are called with one level of - signal blocking. */ -#define MAKEready(what) \ -int \ -fhandler_##what::ready_for_read (int fd, DWORD howlong, int ignra) \ -{ \ - select_record me (this); \ - me.fd = fd; \ - while (select_read (&me) && !me.read_ready && \ - !peek_##what (&me, ignra) && howlong == INFINITE) \ - if (fd >= 0 && cygheap->fdtab.not_open (fd)) \ - break; \ - else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0) \ - break; \ - return me.read_ready; \ -} - #define set_handle_or_return_if_not_open(h, s) \ h = (s)->fh->get_handle (); \ if (cygheap->fdtab.not_open ((s)->fd)) \ @@ -400,13 +382,14 @@ no_verify (select_record *, fd_set *, fd_set *, fd_set *) } static int -peek_pipe (select_record *s, int ignra, HANDLE guard_mutex = NULL) +peek_pipe (select_record *s, int ignra) { int n = 0; int gotone = 0; fhandler_base *fh = s->fh; HANDLE h; + HANDLE guard_mutex = s->fh->get_guard (); set_handle_or_return_if_not_open (h, s); /* Don't perform complicated tests if we don't need to. */ @@ -499,21 +482,6 @@ poll_pipe (select_record *me, fd_set *readfds, fd_set *writefds, 0; } -int -fhandler_pipe::ready_for_read (int fd, DWORD howlong, int ignra) -{ - select_record me (this); - me.fd = fd; - (void) select_read (&me); - while (!peek_pipe (&me, ignra, guard) && howlong == INFINITE) - if (fd >= 0 && cygheap->fdtab.not_open (fd)) - break; - else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0) - break; - select_printf ("returning %d", me.read_ready); - return me.read_ready; -} - static int start_thread_pipe (select_record *me, select_stuff *stuff); struct pipeinf @@ -596,6 +564,7 @@ fhandler_pipe::select_read (select_record *s) s = new select_record; s->startup = start_thread_pipe; s->poll = poll_pipe; + s->peek = peek_pipe; s->verify = verify_ok; s->read_selected = TRUE; s->cleanup = pipe_cleanup; @@ -693,8 +662,6 @@ poll_console (select_record *me, fd_set *readfds, fd_set *writefds, 0; } -MAKEready (console) - select_record * fhandler_console::select_read (select_record *s) { @@ -707,6 +674,7 @@ fhandler_console::select_read (select_record *s) set_cursor_maybe (); } + s->peek = peek_console; s->h = get_handle (); s->read_selected = TRUE; return s; @@ -745,21 +713,6 @@ fhandler_console::select_except (select_record *s) return s; } -int -fhandler_tty_common::ready_for_read (int fd, DWORD howlong, int ignra) -{ - select_record me (this); - me.fd = fd; - (void) select_read (&me); - while (!peek_pipe (&me, ignra) && howlong == INFINITE) - if (fd >= 0 && cygheap->fdtab.not_open (fd)) - break; - else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0) - break; - select_printf ("returning %d", me.read_ready); - return me.read_ready; -} - select_record * fhandler_tty_common::select_read (select_record *s) { @@ -795,6 +748,7 @@ fhandler_tty_slave::select_read (select_record *s) s->h = input_available_event; s->startup = no_startup; s->poll = poll_pipe; + s->peek = peek_pipe; s->verify = verify_tty_slave; s->read_selected = TRUE; s->cleanup = NULL; @@ -805,6 +759,11 @@ int fhandler_tty_slave::ready_for_read (int fd, DWORD howlong, int ignra) { HANDLE w4[2]; + if (!cygheap->fdtab.not_open (fd)) + { + set_errno (EBADF); + return 1; + } if (!ignra && get_readahead_valid ()) { select_printf ("readahead"); @@ -814,13 +773,18 @@ fhandler_tty_slave::ready_for_read (int fd, DWORD howlong, int ignra) w4[1] = input_available_event; switch (WaitForMultipleObjects (2, w4, FALSE, howlong)) { + case WAIT_OBJECT_0: + set_errno (EINTR); + return 0; case WAIT_OBJECT_0 + 1: return 1; case WAIT_FAILED: select_printf ("wait failed %E"); - case WAIT_OBJECT_0: - case WAIT_TIMEOUT: + set_errno (EINVAL); /* FIXME: correct errno? */ + return 0; default: + if (!howlong) + set_errno (EAGAIN); return 0; } } @@ -1058,8 +1022,6 @@ poll_serial (select_record *me, fd_set *readfds, fd_set *writefds, 0; } -MAKEready (serial) - select_record * fhandler_serial::select_read (select_record *s) { @@ -1071,6 +1033,7 @@ fhandler_serial::select_read (select_record *s) s->verify = verify_ok; s->cleanup = serial_cleanup; } + s->peek = peek_serial; s->read_selected = TRUE; return s; } @@ -1107,9 +1070,40 @@ fhandler_serial::select_except (select_record *s) } int -fhandler_base::ready_for_read (int, DWORD, int) +fhandler_base::ready_for_read (int fd, DWORD howlong, int ignra) { - return 1; + int avail = 0; + select_record me (this); + me.fd = fd; + while (!avail) + { + (void) select_read (&me); + avail = me.read_ready ?: me.peek (&me, ignra); + + if (fd >= 0 && cygheap->fdtab.not_open (fd)) + { + set_errno (EBADF); + avail = 0; + break; + } + + if (howlong != INFINITE) + { + if (!avail) + set_errno (EAGAIN); + break; + } + + if (WaitForSingleObject (signal_arrived, avail ? 0 : 10) == WAIT_OBJECT_0) + { + set_errno (EINTR); + avail = 0; + break; + } + } + + select_printf ("read_ready %d, avail %d", me.read_ready, avail); + return avail; } select_record * @@ -1226,8 +1220,6 @@ poll_socket (select_record *me, fd_set *readfds, fd_set *writefds, 0; } -MAKEready (socket) - static int start_thread_socket (select_record *, select_stuff *); static DWORD WINAPI @@ -1406,6 +1398,7 @@ fhandler_socket::select_read (select_record *s) s->verify = verify_true; s->cleanup = socket_cleanup; } + s->peek = peek_socket; s->read_ready = saw_shutdown_read (); s->read_selected = TRUE; return s; @@ -1475,8 +1468,6 @@ poll_windows (select_record *me, fd_set *readfds, fd_set *writefds, 0; } -MAKEready (windows) - select_record * fhandler_windows::select_read (select_record *s) { @@ -1487,6 +1478,7 @@ fhandler_windows::select_read (select_record *s) s->poll = poll_windows; s->verify = poll_windows; } + s->peek = peek_windows; s->h = get_handle (); s->read_selected = TRUE; s->h = get_handle (); |