Rename cygWFMO to cygwait throughout and use the magic of polymorphism to "wait

for stuff".
* fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use simplified arg
form of cygwait.
* fhandler_console.cc (fhandler_console::read): Ditto.
* fhandler_audio.cc (fhandler_dev_dsp::Audio_out::waitforspac): Ditto.
(fhandler_dev_dsp::Audio_in::waitfordata): Ditto.
* fhandler_fifo.cc (fhandler_fifo::wait): Ditto.
* fhandler_serial.cc (fhandler_serial::raw_read): Ditto.
(fhandler_serial::raw_write): Ditto.
* select.cc (cygwin_select): Ditto.
* sigproc.h (cygwait): Rename from cygWFMO.  Define two argument and single
argument forms of this function.
* fhandler_tty.cc (fhandler_pty_slave::open): Use method to query if tty is
open.
(fhandler_pty_slave::read): Send SIGHUP when master is detected as closed.
(fhandler_pty_common::close): Close input_available_event in callers since
master may need to signal it first.
(fhandler_pty_master::close): Lie and set input_available_event when closing,
then close input_available_event.
(fhandler_pty_slave::close): Close input_available_event explicitly here.
* tty.h (tty::is_master_closed): Declare new method.
This commit is contained in:
Christopher Faylor 2011-12-09 16:02:56 +00:00
parent aaaaefc090
commit 57af01797e
10 changed files with 89 additions and 32 deletions

View File

@ -1,3 +1,31 @@
2011-12-09 Christopher Faylor <me.cygwin2011@cgf.cx>
Rename cygWFMO to cygwait throughout and use the magic of polymorphism
to "wait for stuff".
* fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use
simplified arg form of cygwait.
* fhandler_console.cc (fhandler_console::read): Ditto.
* fhandler_audio.cc (fhandler_dev_dsp::Audio_out::waitforspac): Ditto.
(fhandler_dev_dsp::Audio_in::waitfordata): Ditto.
* fhandler_fifo.cc (fhandler_fifo::wait): Ditto.
* fhandler_serial.cc (fhandler_serial::raw_read): Ditto.
(fhandler_serial::raw_write): Ditto.
* select.cc (cygwin_select): Ditto.
* sigproc.h (cygwait): Rename from cygWFMO. Define two argument and
single argument forms of this function.
* fhandler_tty.cc (fhandler_pty_slave::open): Use method to query if
tty is open.
(fhandler_pty_slave::read): Send SIGHUP when master is detected as
closed.
(fhandler_pty_common::close): Close input_available_event in callers
since master may need to signal it first.
(fhandler_pty_master::close): Lie and set input_available_event when
closing, then close input_available_event.
(fhandler_pty_slave::close): Close input_available_event explicitly
here.
* tty.h (tty::is_master_closed): Declare new method.
2011-12-09 Christopher Faylor <me.cygwin2011@cgf.cx>
* sigproc.cc (signal_exit): Revert reversion of 2011-12-04 change

View File

@ -1926,7 +1926,7 @@ 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 = cygWFMO (1, INFINITE, get_overlapped ()->hEvent);
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

View File

@ -348,7 +348,7 @@ fhandler_console::read (void *pv, size_t& buflen)
set_cursor_maybe (); /* to make cursor appear on the screen immediately */
restart:
switch (cygWFMO (1, timeout, h))
switch (cygwait (h, timeout))
{
case WAIT_OBJECT_0:
break;

View File

@ -541,7 +541,7 @@ fhandler_dev_dsp::Audio_out::waitforspace ()
return false;
}
debug_printf ("100ms");
switch (cygWFMO (0, 100))
switch (cygwait (100))
{
case WAIT_OBJECT_0:
if (!_my_tls.call_signal_handler ())
@ -919,7 +919,7 @@ fhandler_dev_dsp::Audio_in::waitfordata ()
return false;
}
debug_printf ("100ms");
switch (cygWFMO (0, 100))
switch (cygwait (100))
{
case WAIT_OBJECT_0:
if (!_my_tls.call_signal_handler ())

View File

@ -216,7 +216,7 @@ fhandler_fifo::wait (HANDLE h)
debug_only_printf ("waiting for %s", what);
/* Wait for the event. Set errno, as appropriate if something goes wrong. */
switch (cygWFMO (1, wait, h))
switch (cygwait (h, wait))
{
case WAIT_OBJECT_0:
debug_only_printf ("successfully waited for %s", what);

View File

@ -96,7 +96,7 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
{
overlapped_armed = 1;
restart:
switch (cygWFMO (1, INFINITE, io_status.hEvent))
switch (cygwait (io_status.hEvent))
{
case WAIT_OBJECT_0:
if (!GetOverlappedResult (get_handle (), &io_status, &n,
@ -203,7 +203,7 @@ fhandler_serial::raw_write (const void *ptr, size_t len)
if (!is_nonblocking ())
{
restart:
switch (cygWFMO (1, INFINITE, write_status.hEvent))
switch (cygwait (write_status.hEvent))
{
case WAIT_OBJECT_0:
break;

View File

@ -428,7 +428,7 @@ fhandler_pty_slave::open (int flags, mode_t)
goto err_no_errno;
}
if (get_ttyp ()->master_pid < 0)
if (get_ttyp ()->is_master_closed ())
{
errmsg = "*** master is closed";
set_errno (EAGAIN);
@ -562,6 +562,8 @@ fhandler_pty_slave::close ()
termios_printf ("closing last open %s handle", ttyname ());
if (inuse && !CloseHandle (inuse))
termios_printf ("CloseHandle (inuse), %E");
if (!ForceCloseHandle (input_available_event))
termios_printf ("CloseHandle (input_available_event<%p>), %E", input_available_event);
return fhandler_pty_common::close ();
}
@ -702,9 +704,15 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
while (len)
{
switch (cygWFMO (1, time_to_wait, input_available_event))
switch (cygwait (input_available_event, time_to_wait))
{
case WAIT_OBJECT_0:
if (get_ttyp ()->is_master_closed ())
{
raise (SIGHUP);
totalread = 0;
goto out;
}
break;
case WAIT_OBJECT_0 + 1:
if (totalread > 0)
@ -738,7 +746,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
}
/* Now that we know that input is available we have to grab the
input mutex. */
switch (cygWFMO (1, 1000, input_mutex))
switch (cygwait (input_mutex, 1000))
{
case WAIT_OBJECT_0:
case WAIT_ABANDONED_0:
@ -811,26 +819,32 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
if (!ReadFile (get_handle (), buf, readlen, &n, NULL))
{
termios_printf ("read failed, %E");
raise (SIGHUP);
}
/* MSDN states that 5th prameter can be used to determine total
number of bytes in pipe, but for some reason this number doesn't
change after successful read. So we have to peek into the pipe
again to see if input is still available */
if (!PeekNamedPipe (get_handle (), peek_buf, 1, &bytes_in_pipe, NULL, NULL))
{
termios_printf ("PeekNamedPipe failed, %E");
bytes_in_pipe = 0;
raise (SIGHUP);
bytes_in_pipe = 0;
ptr = NULL;
}
if (n)
else
{
len -= n;
totalread += n;
if (ptr)
/* MSDN states that 5th prameter can be used to determine total
number of bytes in pipe, but for some reason this number doesn't
change after successful read. So we have to peek into the pipe
again to see if input is still available */
if (!PeekNamedPipe (get_handle (), peek_buf, 1, &bytes_in_pipe, NULL, NULL))
{
memcpy (ptr, buf, n);
ptr = (char *) ptr + n;
termios_printf ("PeekNamedPipe failed, %E");
raise (SIGHUP);
bytes_in_pipe = 0;
}
if (n)
{
len -= n;
totalread += n;
if (ptr)
{
memcpy (ptr, buf, n);
ptr = (char *) ptr + n;
}
}
}
}
@ -1233,9 +1247,6 @@ fhandler_pty_common::close ()
if (!ForceCloseHandle1 (get_output_handle (), to_pty))
termios_printf ("CloseHandle (get_output_handle ()<%p>), %E", get_output_handle ());
if (!ForceCloseHandle (input_available_event))
termios_printf ("CloseHandle (input_available_event<%p>), %E", input_available_event);
return 0;
}
@ -1285,7 +1296,12 @@ fhandler_pty_master::close ()
if (have_execed || get_ttyp ()->master_pid != myself->pid)
termios_printf ("not clearing: %d, master_pid %d", have_execed, get_ttyp ()->master_pid);
else
get_ttyp ()->set_master_closed ();
{
get_ttyp ()->set_master_closed ();
SetEvent (input_available_event);
}
if (!ForceCloseHandle (input_available_event))
termios_printf ("CloseHandle (input_available_event<%p>), %E", input_available_event);
return 0;
}

View File

@ -132,7 +132,7 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
int res = 1;
/* Degenerate case. No fds to wait for. Just wait. */
if (sel.start.next == NULL)
switch (cygWFMO (0, ms))
switch (cygwait (ms))
{
case WAIT_OBJECT_0:
select_printf ("signal received");

View File

@ -81,8 +81,8 @@ void __stdcall sigproc_init ();
#ifdef __INSIDE_CYGWIN__
void __stdcall sigproc_terminate (enum exit_states);
static inline
DWORD cygWFMO (DWORD n, DWORD howlong, ...)
static inline DWORD
cygwait (DWORD n, DWORD howlong, ...)
{
va_list ap;
va_start (ap, howlong);
@ -96,6 +96,18 @@ DWORD cygWFMO (DWORD n, DWORD howlong, ...)
n--;
return WaitForMultipleObjects (n, w4, FALSE, howlong);
}
static inline DWORD
cygwait (HANDLE h, DWORD wait = INFINITE)
{
return cygwait (1, wait, h);
}
static inline DWORD
cygwait (DWORD wait)
{
return cygwait ((DWORD) 0, wait);
}
#endif
bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attribute__ ((regparm (3)));

View File

@ -109,6 +109,7 @@ public:
bool exists ();
bool not_allocated (HANDLE&, HANDLE&);
void set_master_closed () {master_pid = -1;}
bool is_master_closed () const {return master_pid == -1;}
static void __stdcall create_master (int);
static void __stdcall init_session ();
friend class fhandler_pty_master;