* fhandler.h (fhandler_base::has_ongoing_io): Declare virtual method.

* select.cc (peek_pipe): Reorganize slightly.  Don't attempt to check a handle
if it has ongoing I/O.
(select_pipe_info::select_pipe_info): Delete definition.
(select_pipe_info::~select_pipe_info): Delete definition.
(thread_pipe): Get rid of WFMO call.  Reorganize loop.
(pipe_cleanup): Remove dependence on destructor.
(thread_serial): Reorganize loop.
* select.h (select_pipe_info): Empty this class since it no longer has any
special requirements (for now).
* syscalls.cc (readv): Remove an unneeded debug printf.
This commit is contained in:
Christopher Faylor 2010-04-02 22:36:44 +00:00
parent 5151c80c8a
commit 1908518227
5 changed files with 56 additions and 68 deletions

View File

@ -1,3 +1,18 @@
2010-04-02 Christopher Faylor <me+cygwin@cgf.cx>
* fhandler.h (fhandler_base::has_ongoing_io): Declare virtual method.
* select.cc (peek_pipe): Reorganize slightly. Don't attempt to check a
handle if it has ongoing I/O.
(select_pipe_info::select_pipe_info): Delete definition.
(select_pipe_info::~select_pipe_info): Delete definition.
(thread_pipe): Get rid of WFMO call. Reorganize loop.
(pipe_cleanup): Remove dependence on destructor.
(thread_serial): Reorganize loop.
* select.h (select_pipe_info): Empty this class since it no longer has
any special requirements (for now).
* syscalls.cc (readv): Remove an unneeded debug printf.
2010-04-02 Christopher Faylor <me+cygwin@cgf.cx> 2010-04-02 Christopher Faylor <me+cygwin@cgf.cx>
* fhandler.h (fhandler_base::setup_overlapped): Delete virtual * fhandler.h (fhandler_base::setup_overlapped): Delete virtual

View File

@ -386,6 +386,7 @@ class fhandler_base
bool issymlink () {return pc.issymlink ();} bool issymlink () {return pc.issymlink ();}
bool device_access_denied (int) __attribute__ ((regparm (2))); bool device_access_denied (int) __attribute__ ((regparm (2)));
int fhaccess (int flags, bool) __attribute__ ((regparm (3))); int fhaccess (int flags, bool) __attribute__ ((regparm (3)));
virtual bool has_ongoing_io () {return false;}
}; };
class fhandler_mailslot : public fhandler_base class fhandler_mailslot : public fhandler_base

View File

@ -1,7 +1,7 @@
/* select.cc /* select.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009 Red Hat, Inc. 2005, 2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -429,13 +429,18 @@ no_verify (select_record *, fd_set *, fd_set *, fd_set *)
static int static int
peek_pipe (select_record *s, bool from_select) peek_pipe (select_record *s, bool from_select)
{ {
int n = 0;
int gotone = 0;
fhandler_base *fh = s->fh;
HANDLE h; HANDLE h;
set_handle_or_return_if_not_open (h, s); set_handle_or_return_if_not_open (h, s);
int n = 0;
int gotone = 0;
fhandler_base *fh = (fhandler_base *) s->fh;
/* Don't check if this is a non-blocking fd and I/O is still active.
That could give a false-positive with peek_pipe and friends. */
if (fh->has_ongoing_io ())
return 0;
/* Don't perform complicated tests if we don't need to. */ /* Don't perform complicated tests if we don't need to. */
if (!s->read_selected && !s->except_selected) if (!s->read_selected && !s->except_selected)
goto out; goto out;
@ -577,65 +582,35 @@ out:
static int start_thread_pipe (select_record *me, select_stuff *stuff); static int start_thread_pipe (select_record *me, select_stuff *stuff);
select_pipe_info::select_pipe_info ()
{
n = 1;
w4[0] = CreateEvent (&sec_none_nih, true, false, NULL);
}
select_pipe_info::~select_pipe_info ()
{
if (thread)
{
SetEvent (w4[0]);
stop_thread = true;
thread->detach ();
}
ForceCloseHandle (w4[0]);
}
static DWORD WINAPI static DWORD WINAPI
thread_pipe (void *arg) thread_pipe (void *arg)
{ {
select_pipe_info *pi = (select_pipe_info *) arg; select_pipe_info *pi = (select_pipe_info *) arg;
bool gotone = false;
DWORD sleep_time = 0; DWORD sleep_time = 0;
bool looping = true;
for (;;) while (looping)
{ {
select_record *s = pi->start; for (select_record *s = pi->start; (s = s->next); )
if (pi->n > 1)
switch (WaitForMultipleObjects (pi->n, pi->w4, false, INFINITE))
{
case WAIT_OBJECT_0:
goto out;
default:
break;
}
while ((s = s->next))
if (s->startup == start_thread_pipe) if (s->startup == start_thread_pipe)
{ {
if (peek_pipe (s, true)) if (peek_pipe (s, true))
gotone = true; looping = false;
if (pi->stop_thread) if (pi->stop_thread)
{ {
select_printf ("stopping"); select_printf ("stopping");
goto out; looping = false;
break;
} }
} }
/* Paranoid check */ if (!looping)
if (pi->stop_thread)
{
select_printf ("stopping from outer loop");
break;
}
if (gotone)
break; break;
Sleep (sleep_time >> 3); Sleep (sleep_time >> 3);
if (sleep_time < 80) if (sleep_time < 80)
++sleep_time; ++sleep_time;
if (pi->stop_thread)
break;
} }
out:
return 0; return 0;
} }
@ -660,9 +635,12 @@ start_thread_pipe (select_record *me, select_stuff *stuff)
static void static void
pipe_cleanup (select_record *, select_stuff *stuff) pipe_cleanup (select_record *, select_stuff *stuff)
{ {
if (stuff->device_specific_pipe) select_pipe_info *pi = (select_pipe_info *) stuff->device_specific_pipe;
if (pi && pi->thread)
{ {
delete stuff->device_specific_pipe; pi->stop_thread = true;
pi->thread->detach ();
delete pi;
stuff->device_specific_pipe = NULL; stuff->device_specific_pipe = NULL;
} }
} }
@ -1119,25 +1097,23 @@ static DWORD WINAPI
thread_serial (void *arg) thread_serial (void *arg)
{ {
select_serial_info *si = (select_serial_info *) arg; select_serial_info *si = (select_serial_info *) arg;
bool gotone = false; bool looping = true;
for (;;) while (looping)
{ for (select_record *s = si->start; (s = s->next); )
select_record *s = si->start; if (s->startup != start_thread_serial)
while ((s = s->next)) continue;
if (s->startup == start_thread_serial) else
{
if (peek_serial (s, true))
gotone = true;
}
if (si->stop_thread)
{ {
select_printf ("stopping"); if (peek_serial (s, true))
break; looping = false;
if (si->stop_thread)
{
select_printf ("stopping");
looping = false;
break;
}
} }
if (gotone)
break;
}
select_printf ("exiting"); select_printf ("exiting");
return 0; return 0;

View File

@ -1,7 +1,7 @@
/* select.h /* select.h
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009 Red Hat, Inc. 2005, 2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -49,10 +49,6 @@ struct select_info
struct select_pipe_info: public select_info struct select_pipe_info: public select_info
{ {
DWORD n;
HANDLE w4[MAXIMUM_WAIT_OBJECTS];
select_pipe_info ();
~select_pipe_info ();
}; };
struct select_socket_info: public select_info struct select_socket_info: public select_info

View File

@ -913,7 +913,7 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
fd, iov, iovcnt, wait ? "" : "non", sigcatchers); fd, iov, iovcnt, wait ? "" : "non", sigcatchers);
if (wait && (!cfd->is_slow () || cfd->uninterruptible_io ())) if (wait && (!cfd->is_slow () || cfd->uninterruptible_io ()))
debug_printf ("no need to call ready_for_read"); /* no need to call ready_for_read */;
else if (!cfd->ready_for_read (fd, wait)) else if (!cfd->ready_for_read (fd, wait))
{ {
res = -1; res = -1;