[PATCH] Re: Cygwin select() issues and improvements
john hood
cgull@glup.org
Sat Mar 19 22:44:00 GMT 2016
On 3/17/16 12:37 PM, Eric Blake wrote:
> But that's where 'git rebase' is your friend. Just because your original
> series wasn't perfect doesn't mean you can avoid cleaning things up and
> posting an improved version. The goal of patch submissions is to make
> the reviewer's job easier, even if it makes it longer for you to post
> the perfect patch series.
I was coming down sick when I wrote that first email and my logic was
not impeccable...
Here's a patch series with hopefully-reasonable changelog-style git
comments.
regards,
--jh
-------------- next part --------------
From c805552cdc9e673ef2330388ddb8b7a0da741766 Mon Sep 17 00:00:00 2001
From: John Hood <cgull@glup.org>
Date: Thu, 28 Jan 2016 17:08:39 -0500
Subject: [PATCH 1/5] Use high-resolution timebases for select().
* cygwait.h: Add cygwait_us() methods.
* select.h: Change prototype for select_stuff::wait() for larger
microsecond timeouts.
* select.cc (pselect): Convert from old cygwin_select().
Implement microsecond timeouts.
(cygwin_select): Rewrite as a wrapper on pselect().
(select): Implement microsecond timeouts.
(select_stuff::wait): Implement microsecond timeouts with a timer
object.
---
winsup/cygwin/cygwait.h | 27 +++++++
winsup/cygwin/select.cc | 182 ++++++++++++++++++++++++++++++------------------
winsup/cygwin/select.h | 2 +-
3 files changed, 141 insertions(+), 70 deletions(-)
diff --git a/winsup/cygwin/cygwait.h b/winsup/cygwin/cygwait.h
index 1240f54..3e02cdd 100644
--- a/winsup/cygwin/cygwait.h
+++ b/winsup/cygwin/cygwait.h
@@ -59,3 +59,30 @@ cygwait (DWORD howlong)
{
return cygwait (NULL, howlong);
}
+
+extern inline DWORD __attribute__ ((always_inline))
+cygwait_us (HANDLE h, LONGLONG howlong, unsigned mask)
+{
+ LARGE_INTEGER li_howlong;
+ PLARGE_INTEGER pli_howlong;
+ if (howlong < 0LL)
+ pli_howlong = NULL;
+ else
+ {
+ li_howlong.QuadPart = -(10LL * howlong);
+ pli_howlong = &li_howlong;
+ }
+ return cygwait (h, pli_howlong, mask);
+}
+
+static inline DWORD __attribute__ ((always_inline))
+cygwait_us (HANDLE h, LONGLONG howlong = -1)
+{
+ return cygwait_us (h, howlong, cw_cancel | cw_sig);
+}
+
+static inline DWORD __attribute__ ((always_inline))
+cygwait_us (LONGLONG howlong)
+{
+ return cygwait_us (NULL, howlong);
+}
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 1f3276c..8f759a4 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -85,41 +85,68 @@ details. */
return -1; \
}
-static int select (int, fd_set *, fd_set *, fd_set *, DWORD);
+static int select (int, fd_set *, fd_set *, fd_set *, LONGLONG);
/* The main select code. */
extern "C" int
-cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- struct timeval *to)
+pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ const struct timespec *to, const sigset_t *set)
{
- select_printf ("select(%d, %p, %p, %p, %p)", maxfds, readfds, writefds, exceptfds, to);
+ sigset_t oldset = _my_tls.sigmask;
- pthread_testcancel ();
- int res;
- if (maxfds < 0)
- {
- set_errno (EINVAL);
- res = -1;
- }
- else
+ __try
{
- /* Convert to milliseconds or INFINITE if to == NULL */
- DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE;
- if (ms == 0 && to->tv_usec)
- ms = 1; /* At least 1 ms granularity */
+ if (set)
+ set_signal_mask (_my_tls.sigmask, *set);
+
+ select_printf ("pselect(%d, %p, %p, %p, %p, %p)", maxfds, readfds, writefds, exceptfds, to, set);
- if (to)
- select_printf ("to->tv_sec %ld, to->tv_usec %ld, ms %d", to->tv_sec, to->tv_usec, ms);
+ pthread_testcancel ();
+ int res;
+ if (maxfds < 0)
+ {
+ set_errno (EINVAL);
+ res = -1;
+ }
else
- select_printf ("to NULL, ms %x", ms);
+ {
+ /* Convert to microseconds or -1 if to == NULL */
+ LONGLONG us = to ? to->tv_sec * 1000000LL + (to->tv_nsec + 999) / 1000 : -1LL;
+
+ if (to)
+ select_printf ("to->tv_sec %ld, to->tv_nsec %ld, us %lld", to->tv_sec, to->tv_nsec, us);
+ else
+ select_printf ("to NULL, us %lld", us);
+
+ res = select (maxfds, readfds ?: allocfd_set (maxfds),
+ writefds ?: allocfd_set (maxfds),
+ exceptfds ?: allocfd_set (maxfds), us);
+ }
+ syscall_printf ("%R = select(%d, %p, %p, %p, %p)", res, maxfds, readfds,
+ writefds, exceptfds, to);
- res = select (maxfds, readfds ?: allocfd_set (maxfds),
- writefds ?: allocfd_set (maxfds),
- exceptfds ?: allocfd_set (maxfds), ms);
+ if (set)
+ set_signal_mask (_my_tls.sigmask, oldset);
+ return res;
}
- syscall_printf ("%R = select(%d, %p, %p, %p, %p)", res, maxfds, readfds,
- writefds, exceptfds, to);
- return res;
+ __except (EFAULT) {}
+ __endtry
+ return -1;
+}
+
+/* select() is just a wrapper on pselect(). */
+extern "C" int
+cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ struct timeval *to)
+{
+ struct timespec ts;
+ if (to)
+ {
+ ts.tv_sec = to->tv_sec;
+ ts.tv_nsec = to->tv_usec * 1000;
+ }
+ return pselect (maxfds, readfds, writefds, exceptfds,
+ to ? &ts : NULL, NULL);
}
/* This function is arbitrarily split out from cygwin_select to avoid odd
@@ -127,13 +154,13 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
for the sel variable. */
static int
select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- DWORD ms)
+ LONGLONG us)
{
select_stuff::wait_states wait_state = select_stuff::select_loop;
int ret = 0;
/* Record the current time for later use. */
- LONGLONG start_time = gtod.msecs ();
+ LONGLONG start_time = gtod.usecs ();
select_stuff sel;
sel.return_on_signal = 0;
@@ -158,7 +185,7 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
/* Degenerate case. No fds to wait for. Just wait for time to run out
or signal to arrive. */
if (sel.start.next == NULL)
- switch (cygwait (ms))
+ switch (cygwait_us (us))
{
case WAIT_SIGNALED:
select_printf ("signal received");
@@ -178,12 +205,12 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
wait_state = select_stuff::select_set_zero;
break;
}
- else if (sel.always_ready || ms == 0)
+ else if (sel.always_ready || us == 0)
/* Catch any active fds via sel.poll() below */
wait_state = select_stuff::select_ok;
else
/* wait for an fd to become active or time out */
- wait_state = sel.wait (r, w, e, ms);
+ wait_state = sel.wait (r, w, e, us);
select_printf ("sel.wait returns %d", wait_state);
@@ -209,11 +236,11 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
sel.cleanup ();
sel.destroy ();
/* Recalculate time remaining to wait if we are going to be looping. */
- if (wait_state == select_stuff::select_loop && ms != INFINITE)
+ if (wait_state == select_stuff::select_loop && us != -1)
{
- select_printf ("recalculating ms");
- LONGLONG now = gtod.msecs ();
- if (now > (start_time + ms))
+ select_printf ("recalculating us");
+ LONGLONG now = gtod.usecs ();
+ if (now > (start_time + us))
{
select_printf ("timed out after verification");
/* Set descriptor bits to zero per POSIX. */
@@ -225,9 +252,9 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
}
else
{
- ms -= (now - start_time);
+ us -= (now - start_time);
start_time = now;
- select_printf ("ms now %u", ms);
+ select_printf ("us now %lld", us);
}
}
}
@@ -238,33 +265,6 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
return ret;
}
-extern "C" int
-pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- const struct timespec *ts, const sigset_t *set)
-{
- struct timeval tv;
- sigset_t oldset = _my_tls.sigmask;
-
- __try
- {
- if (ts)
- {
- tv.tv_sec = ts->tv_sec;
- tv.tv_usec = ts->tv_nsec / 1000;
- }
- if (set)
- set_signal_mask (_my_tls.sigmask, *set);
- int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
- ts ? &tv : NULL);
- if (set)
- set_signal_mask (_my_tls.sigmask, oldset);
- return ret;
- }
- __except (EFAULT) {}
- __endtry
- return -1;
-}
-
/* Call cleanup functions for all inspected fds. Gets rid of any
executing threads. */
void
@@ -362,13 +362,50 @@ err:
/* The heart of select. Waits for an fd to do something interesting. */
select_stuff::wait_states
select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- DWORD ms)
+ LONGLONG us)
{
HANDLE w4[MAXIMUM_WAIT_OBJECTS];
select_record *s = &start;
DWORD m = 0;
+ /* Always wait for signals. */
wait_signal_arrived here (w4[m++]);
+
+ /* Set a timeout, or not, for WMFO. */
+ DWORD dTimeoutMs;
+ if (us == 0)
+ {
+ dTimeoutMs = 0;
+ }
+ else
+ {
+ dTimeoutMs = INFINITE;
+ }
+ /* Create and set a waitable timer, if a finite timeout has been
+ requested. */
+ LARGE_INTEGER liTimeout;
+ HANDLE hTimeout;
+ NTSTATUS status;
+ status = NtCreateTimer(&hTimeout, TIMER_ALL_ACCESS, NULL, NotificationTimer);
+ if (!NT_SUCCESS (status))
+ {
+ select_printf("NtCreateTimer failed (%d)\n", GetLastError());
+ return select_error;
+ }
+ w4[m++] = hTimeout;
+ if (us >= 0)
+ {
+ liTimeout.QuadPart = -us * 10;
+ int setret;
+ status = NtSetTimer (hTimeout, &liTimeout, NULL, NULL, FALSE, 0, NULL);
+ if (!NT_SUCCESS(status))
+ {
+ select_printf ("NtSetTimer failed: %d (%08x)\n", setret, GetLastError());
+ return select_error;
+ }
+ }
+
+ /* Optionally wait for pthread cancellation. */
if ((w4[m] = pthread::get_cancel_event ()) != NULL)
m++;
@@ -397,21 +434,27 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
next_while:;
}
- debug_printf ("m %d, ms %u", m, ms);
+ debug_printf ("m %d, us %llu, dTimeoutMs %d", m, us, dTimeoutMs);
DWORD wait_ret;
if (!windows_used)
- wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
+ wait_ret = WaitForMultipleObjects (m, w4, FALSE, dTimeoutMs);
else
/* Using MWMO_INPUTAVAILABLE is the officially supported solution for
the problem that the call to PeekMessage disarms the queue state
so that a subsequent MWFMO hangs, even if there are still messages
in the queue. */
- wait_ret = MsgWaitForMultipleObjectsEx (m, w4, ms,
+ wait_ret = MsgWaitForMultipleObjectsEx (m, w4, dTimeoutMs,
QS_ALLINPUT | QS_ALLPOSTMESSAGE,
MWMO_INPUTAVAILABLE);
select_printf ("wait_ret %d, m = %d. verifying", wait_ret, m);
+ if (dTimeoutMs == INFINITE)
+ {
+ CancelWaitableTimer (hTimeout);
+ CloseHandle (hTimeout);
+ }
+
wait_states res;
switch (wait_ret)
{
@@ -434,12 +477,13 @@ next_while:;
s->set_select_errno ();
res = select_error;
break;
+ case WAIT_OBJECT_0 + 1:
case WAIT_TIMEOUT:
select_printf ("timed out");
res = select_set_zero;
break;
- case WAIT_OBJECT_0 + 1:
- if (startfds > 1)
+ case WAIT_OBJECT_0 + 2:
+ if (startfds > 2)
{
cleanup ();
destroy ();
diff --git a/winsup/cygwin/select.h b/winsup/cygwin/select.h
index 0035820..581ee4e 100644
--- a/winsup/cygwin/select.h
+++ b/winsup/cygwin/select.h
@@ -96,7 +96,7 @@ public:
bool test_and_set (int, fd_set *, fd_set *, fd_set *);
int poll (fd_set *, fd_set *, fd_set *);
- wait_states wait (fd_set *, fd_set *, fd_set *, DWORD);
+ wait_states wait (fd_set *, fd_set *, fd_set *, LONGLONG);
void cleanup ();
void destroy ();
--
2.7.2
-------------- next part --------------
From 225f852594d9ff6a1231063ece3d529b9cc1bf7f Mon Sep 17 00:00:00 2001
From: John Hood <cgull@glup.org>
Date: Sat, 30 Jan 2016 17:33:36 -0500
Subject: [PATCH 2/5] Move get_nonascii_key into fhandler_console.
* fhandler.h (fhandler_console): Move get_nonascii_key() from
select.c into this class.
* select.cc (peek_console): Move get_nonascii_key() into
fhandler_console class.
---
winsup/cygwin/fhandler.h | 1 +
winsup/cygwin/fhandler_console.cc | 4 +---
winsup/cygwin/select.cc | 3 +--
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 1c1862b..2dbe377 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1469,6 +1469,7 @@ private:
bool set_unit ();
static bool need_invisible ();
static void free_console ();
+ static const char *get_nonascii_key (INPUT_RECORD& input_rec, char *);
fhandler_console (void *) {}
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index ef2d1c5..f683e90 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -46,8 +46,6 @@ details. */
#define srTop (con.b.srWindow.Top + con.scroll_region.Top)
#define srBottom ((con.scroll_region.Bottom < 0) ? con.b.srWindow.Bottom : con.b.srWindow.Top + con.scroll_region.Bottom)
-const char *get_nonascii_key (INPUT_RECORD&, char *);
-
const unsigned fhandler_console::MAX_WRITE_CHARS = 16384;
fhandler_console::console_state NO_COPY *fhandler_console::shared_console_info;
@@ -2391,7 +2389,7 @@ static const struct {
};
const char *
-get_nonascii_key (INPUT_RECORD& input_rec, char *tmp)
+fhandler_console::get_nonascii_key (INPUT_RECORD& input_rec, char *tmp)
{
#define NORMAL 0
#define SHIFT 1
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 8f759a4..10205a0 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -883,7 +883,6 @@ fhandler_fifo::select_except (select_stuff *ss)
static int
peek_console (select_record *me, bool)
{
- extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *);
fhandler_console *fh = (fhandler_console *) me->fh;
if (!me->read_selected)
@@ -925,7 +924,7 @@ peek_console (select_record *me, bool)
{
if (irec.Event.KeyEvent.bKeyDown
&& (irec.Event.KeyEvent.uChar.AsciiChar
- || get_nonascii_key (irec, tmpbuf)))
+ || fhandler_console::get_nonascii_key (irec, tmpbuf)))
return me->read_ready = true;
}
else
--
2.7.2
-------------- next part --------------
From b2e2b5ac1d6b62610c51a66113e5ab97b1d43750 Mon Sep 17 00:00:00 2001
From: John Hood <cgull@glup.org>
Date: Sat, 30 Jan 2016 17:37:33 -0500
Subject: [PATCH 3/5] Debug printfs.
* fhandler.cc (fhandler_base::get_readahead): Add debug code.
* fhandler_console.cc (fhandler_console::read): Add debug code.
* select.cc (pselect): Add debug code.
(peek_console): Add debug code.
---
winsup/cygwin/fhandler.cc | 1 +
winsup/cygwin/fhandler_console.cc | 10 +++++++++-
winsup/cygwin/select.cc | 12 +++++++++++-
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 33743d4..86f77c3 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -90,6 +90,7 @@ fhandler_base::get_readahead ()
/* FIXME - not thread safe */
if (raixget >= ralen)
raixget = raixput = ralen = 0;
+ debug_printf("available: %d", chret > -1);
return chret;
}
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index f683e90..5dd071c 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -309,6 +309,8 @@ fhandler_console::read (void *pv, size_t& buflen)
int ch;
set_input_state ();
+ debug_printf("requested buflen %d", buflen);
+
/* Check console read-ahead buffer filled from terminal requests */
if (con.cons_rapoi && *con.cons_rapoi)
{
@@ -318,6 +320,7 @@ fhandler_console::read (void *pv, size_t& buflen)
}
int copied_chars = get_readahead_into_buffer (buf, buflen);
+ debug_printf("copied_chars %d", copied_chars);
if (copied_chars)
{
@@ -695,9 +698,11 @@ fhandler_console::read (void *pv, size_t& buflen)
continue;
}
+ debug_printf("toadd = %p, nread = %d", toadd, nread);
if (toadd)
{
- line_edit_status res = line_edit (toadd, nread, ti);
+ ssize_t bytes_read;
+ line_edit_status res = line_edit (toadd, nread, ti, &bytes_read);
if (res == line_edit_signalled)
goto sig_exit;
else if (res == line_edit_input_done)
@@ -705,6 +710,8 @@ fhandler_console::read (void *pv, size_t& buflen)
}
}
+ debug_printf("ralen = %d, bytes = %d", ralen, ralen - raixget);
+
while (buflen)
if ((ch = get_readahead ()) < 0)
break;
@@ -716,6 +723,7 @@ fhandler_console::read (void *pv, size_t& buflen)
#undef buf
buflen = copied_chars;
+ debug_printf("buflen set to %d", buflen);
return;
err:
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 10205a0..25b0c5a 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -925,18 +925,28 @@ peek_console (select_record *me, bool)
if (irec.Event.KeyEvent.bKeyDown
&& (irec.Event.KeyEvent.uChar.AsciiChar
|| fhandler_console::get_nonascii_key (irec, tmpbuf)))
- return me->read_ready = true;
+ {
+ debug_printf("peeked KEY_EVENT");
+ return me->read_ready = true;
+ }
}
else
{
if (irec.EventType == MOUSE_EVENT
&& fh->mouse_aware (irec.Event.MouseEvent))
+ {
+ debug_printf("peeked MOUSE_EVENT");
return me->read_ready = true;
+ }
if (irec.EventType == FOCUS_EVENT && fh->focus_aware ())
+ {
+ debug_printf("peeked FOCUS_EVENT");
return me->read_ready = true;
+ }
}
/* Read and discard the event */
+ debug_printf("discarded other event");
ReadConsoleInput (h, &irec, 1, &events_read);
}
--
2.7.2
-------------- next part --------------
From cf2db014fefd4a8488316cf9313325b79e25518d Mon Sep 17 00:00:00 2001
From: John Hood <cgull@glup.org>
Date: Thu, 4 Feb 2016 00:44:56 -0500
Subject: [PATCH 4/5] Improve and simplify select().
* cygwait.h (cygwait_us) Remove; this reverts previous changes.
* select.h: Eliminate redundant select_stuff::select_loop state.
* select.cc (select): Eliminate redundant
select_stuff::select_loop state. Eliminate redundant code for
zero timeout. Do not return early on early timer return.
(select_stuff::wait): Eliminate redundant
select_stuff::select_loop state.
---
winsup/cygwin/cygwait.h | 27 ---------------------
winsup/cygwin/select.cc | 63 ++++++++++++-------------------------------------
winsup/cygwin/select.h | 1 -
3 files changed, 15 insertions(+), 76 deletions(-)
diff --git a/winsup/cygwin/cygwait.h b/winsup/cygwin/cygwait.h
index 3e02cdd..1240f54 100644
--- a/winsup/cygwin/cygwait.h
+++ b/winsup/cygwin/cygwait.h
@@ -59,30 +59,3 @@ cygwait (DWORD howlong)
{
return cygwait (NULL, howlong);
}
-
-extern inline DWORD __attribute__ ((always_inline))
-cygwait_us (HANDLE h, LONGLONG howlong, unsigned mask)
-{
- LARGE_INTEGER li_howlong;
- PLARGE_INTEGER pli_howlong;
- if (howlong < 0LL)
- pli_howlong = NULL;
- else
- {
- li_howlong.QuadPart = -(10LL * howlong);
- pli_howlong = &li_howlong;
- }
- return cygwait (h, pli_howlong, mask);
-}
-
-static inline DWORD __attribute__ ((always_inline))
-cygwait_us (HANDLE h, LONGLONG howlong = -1)
-{
- return cygwait_us (h, howlong, cw_cancel | cw_sig);
-}
-
-static inline DWORD __attribute__ ((always_inline))
-cygwait_us (LONGLONG howlong)
-{
- return cygwait_us (NULL, howlong);
-}
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 25b0c5a..556a79f 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -32,7 +32,6 @@ details. */
#include "pinfo.h"
#include "sigproc.h"
#include "cygtls.h"
-#include "cygwait.h"
/*
* All these defines below should be in sys/types.h
@@ -156,7 +155,7 @@ static int
select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
LONGLONG us)
{
- select_stuff::wait_states wait_state = select_stuff::select_loop;
+ select_stuff::wait_states wait_state = select_stuff::select_set_zero;
int ret = 0;
/* Record the current time for later use. */
@@ -182,30 +181,7 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
}
select_printf ("sel.always_ready %d", sel.always_ready);
- /* Degenerate case. No fds to wait for. Just wait for time to run out
- or signal to arrive. */
- if (sel.start.next == NULL)
- switch (cygwait_us (us))
- {
- case WAIT_SIGNALED:
- select_printf ("signal received");
- /* select() is always interrupted by a signal so set EINTR,
- unconditionally, ignoring any SA_RESTART detection by
- call_signal_handler(). */
- _my_tls.call_signal_handler ();
- set_sig_errno (EINTR);
- wait_state = select_stuff::select_signalled;
- break;
- case WAIT_CANCELED:
- sel.destroy ();
- pthread::static_cancel_self ();
- /*NOTREACHED*/
- default:
- /* Set wait_state to zero below. */
- wait_state = select_stuff::select_set_zero;
- break;
- }
- else if (sel.always_ready || us == 0)
+ if (sel.always_ready || us == 0)
/* Catch any active fds via sel.poll() below */
wait_state = select_stuff::select_ok;
else
@@ -214,29 +190,24 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
select_printf ("sel.wait returns %d", wait_state);
- if (wait_state >= select_stuff::select_ok)
+ if (wait_state == select_stuff::select_ok)
{
UNIX_FD_ZERO (readfds, maxfds);
UNIX_FD_ZERO (writefds, maxfds);
UNIX_FD_ZERO (exceptfds, maxfds);
- if (wait_state == select_stuff::select_set_zero)
- ret = 0;
- else
- {
- /* Set bit mask from sel records. This also sets ret to the
- right value >= 0, matching the number of bits set in the
- fds records. if ret is 0, continue to loop. */
- ret = sel.poll (readfds, writefds, exceptfds);
- if (!ret)
- wait_state = select_stuff::select_loop;
- }
+ /* Set bit mask from sel records. This also sets ret to the
+ right value >= 0, matching the number of bits set in the
+ fds records. if ret is 0, continue to loop. */
+ ret = sel.poll (readfds, writefds, exceptfds);
+ if (!ret)
+ wait_state = select_stuff::select_set_zero;
}
/* Always clean up everything here. If we're looping then build it
all up again. */
sel.cleanup ();
sel.destroy ();
- /* Recalculate time remaining to wait if we are going to be looping. */
- if (wait_state == select_stuff::select_loop && us != -1)
+ /* Check and recalculate timeout. */
+ if (us != -1LL && wait_state == select_stuff::select_set_zero)
{
select_printf ("recalculating us");
LONGLONG now = gtod.usecs ();
@@ -258,7 +229,7 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
}
}
}
- while (wait_state == select_stuff::select_loop);
+ while (wait_state == select_stuff::select_set_zero);
if (wait_state < select_stuff::select_ok)
ret = -1;
@@ -494,7 +465,7 @@ next_while:;
to wait for. */
default:
s = &start;
- bool gotone = false;
+ res = select_set_zero;
/* Some types of objects (e.g., consoles) wake up on "inappropriate"
events like mouse movements. The verify function will detect these
situations. If it returns false, then this wakeup was a false alarm
@@ -508,13 +479,9 @@ next_while:;
}
else if ((((wait_ret >= m && s->windows_handle) || s->h == w4[wait_ret]))
&& s->verify (s, readfds, writefds, exceptfds))
- gotone = true;
+ res = select_ok;
- if (!gotone)
- res = select_loop;
- else
- res = select_ok;
- select_printf ("gotone %d", gotone);
+ select_printf ("res after verify %d", res);
break;
}
out:
diff --git a/winsup/cygwin/select.h b/winsup/cygwin/select.h
index 581ee4e..3c749ad 100644
--- a/winsup/cygwin/select.h
+++ b/winsup/cygwin/select.h
@@ -78,7 +78,6 @@ public:
enum wait_states
{
select_signalled = -3,
- select_loop = -2,
select_error = -1,
select_ok = 0,
select_set_zero = 1
--
2.7.2
-------------- next part --------------
From 3f3f7112f948d70c15046641cf3cc898a9ca4c71 Mon Sep 17 00:00:00 2001
From: John Hood <cgull@glup.org>
Date: Fri, 18 Mar 2016 04:31:16 -0400
Subject: [PATCH 5/5] * winsup/testsuite/configure: chmod a+x
---
winsup/testsuite/configure | 0
1 file changed, 0 insertions(+), 0 deletions(-)
mode change 100644 => 100755 winsup/testsuite/configure
diff --git a/winsup/testsuite/configure b/winsup/testsuite/configure
old mode 100644
new mode 100755
--
2.7.2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: OpenPGP digital signature
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20160319/8e06eb1e/attachment.sig>
More information about the Cygwin-patches
mailing list