Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2010-04-03 02:36:44 +0400
committerChristopher Faylor <me@cgf.cx>2010-04-03 02:36:44 +0400
commit1908518227ea55036df2a38581e24b57d48ea0cf (patch)
tree87a83e3ea8d13ceda6176c118714c0dcc4f9f9bf /winsup/cygwin/select.cc
parent5151c80c8a6b9dcb6d6e3aa45df8f1a80414582b (diff)
* 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.
Diffstat (limited to 'winsup/cygwin/select.cc')
-rw-r--r--winsup/cygwin/select.cc98
1 files changed, 37 insertions, 61 deletions
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 4fd886131..41636d179 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -1,7 +1,7 @@
/* select.cc
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.
@@ -429,12 +429,17 @@ no_verify (select_record *, fd_set *, fd_set *, fd_set *)
static int
peek_pipe (select_record *s, bool from_select)
{
+ HANDLE h;
+ set_handle_or_return_if_not_open (h, s);
+
int n = 0;
int gotone = 0;
- fhandler_base *fh = s->fh;
+ fhandler_base *fh = (fhandler_base *) s->fh;
- HANDLE h;
- set_handle_or_return_if_not_open (h, s);
+ /* 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. */
if (!s->read_selected && !s->except_selected)
@@ -577,65 +582,35 @@ out:
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
thread_pipe (void *arg)
{
select_pipe_info *pi = (select_pipe_info *) arg;
- bool gotone = false;
DWORD sleep_time = 0;
+ bool looping = true;
- for (;;)
+ while (looping)
{
- select_record *s = pi->start;
- if (pi->n > 1)
- switch (WaitForMultipleObjects (pi->n, pi->w4, false, INFINITE))
- {
- case WAIT_OBJECT_0:
- goto out;
- default:
- break;
- }
- while ((s = s->next))
+ for (select_record *s = pi->start; (s = s->next); )
if (s->startup == start_thread_pipe)
{
if (peek_pipe (s, true))
- gotone = true;
+ looping = false;
if (pi->stop_thread)
{
select_printf ("stopping");
- goto out;
+ looping = false;
+ break;
}
}
- /* Paranoid check */
- if (pi->stop_thread)
- {
- select_printf ("stopping from outer loop");
- break;
- }
- if (gotone)
+ if (!looping)
break;
Sleep (sleep_time >> 3);
if (sleep_time < 80)
++sleep_time;
+ if (pi->stop_thread)
+ break;
}
-out:
return 0;
}
@@ -660,9 +635,12 @@ start_thread_pipe (select_record *me, select_stuff *stuff)
static void
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;
}
}
@@ -1119,25 +1097,23 @@ static DWORD WINAPI
thread_serial (void *arg)
{
select_serial_info *si = (select_serial_info *) arg;
- bool gotone = false;
+ bool looping = true;
- for (;;)
- {
- select_record *s = si->start;
- while ((s = s->next))
- if (s->startup == start_thread_serial)
- {
- if (peek_serial (s, true))
- gotone = true;
- }
- if (si->stop_thread)
+ while (looping)
+ for (select_record *s = si->start; (s = s->next); )
+ if (s->startup != start_thread_serial)
+ continue;
+ else
{
- select_printf ("stopping");
- break;
+ if (peek_serial (s, true))
+ looping = false;
+ if (si->stop_thread)
+ {
+ select_printf ("stopping");
+ looping = false;
+ break;
+ }
}
- if (gotone)
- break;
- }
select_printf ("exiting");
return 0;