Revert "Use high-resolution timebases for select()."

This reverts commit 6e70fd315a.

Revert accidental push
This commit is contained in:
Corinna Vinschen 2016-03-20 21:59:47 +01:00
parent bf0f4baf95
commit 58988463cc
3 changed files with 72 additions and 143 deletions

View File

@ -59,30 +59,3 @@ cygwait (DWORD howlong)
{ {
return cygwait (NULL, 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);
}

View File

@ -85,68 +85,41 @@ details. */
return -1; \ return -1; \
} }
static int select (int, fd_set *, fd_set *, fd_set *, LONGLONG); static int select (int, fd_set *, fd_set *, fd_set *, DWORD);
/* The main select code. */ /* The main select code. */
extern "C" int extern "C" int
pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *to, const sigset_t *set)
{
sigset_t oldset = _my_tls.sigmask;
__try
{
if (set)
set_signal_mask (_my_tls.sigmask, *set);
select_printf ("pselect(%d, %p, %p, %p, %p, %p)", maxfds, readfds, writefds, exceptfds, to, set);
pthread_testcancel ();
int res;
if (maxfds < 0)
{
set_errno (EINVAL);
res = -1;
}
else
{
/* 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);
if (set)
set_signal_mask (_my_tls.sigmask, oldset);
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, cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *to) struct timeval *to)
{ {
struct timespec ts; select_printf ("select(%d, %p, %p, %p, %p)", maxfds, readfds, writefds, exceptfds, to);
if (to)
pthread_testcancel ();
int res;
if (maxfds < 0)
{ {
ts.tv_sec = to->tv_sec; set_errno (EINVAL);
ts.tv_nsec = to->tv_usec * 1000; res = -1;
} }
return pselect (maxfds, readfds, writefds, exceptfds, else
to ? &ts : NULL, NULL); {
/* 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 (to)
select_printf ("to->tv_sec %ld, to->tv_usec %ld, ms %d", to->tv_sec, to->tv_usec, ms);
else
select_printf ("to NULL, ms %x", ms);
res = select (maxfds, readfds ?: allocfd_set (maxfds),
writefds ?: allocfd_set (maxfds),
exceptfds ?: allocfd_set (maxfds), ms);
}
syscall_printf ("%R = select(%d, %p, %p, %p, %p)", res, maxfds, readfds,
writefds, exceptfds, to);
return res;
} }
/* This function is arbitrarily split out from cygwin_select to avoid odd /* This function is arbitrarily split out from cygwin_select to avoid odd
@ -154,13 +127,13 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
for the sel variable. */ for the sel variable. */
static int static int
select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
LONGLONG us) DWORD ms)
{ {
select_stuff::wait_states wait_state = select_stuff::select_loop; select_stuff::wait_states wait_state = select_stuff::select_loop;
int ret = 0; int ret = 0;
/* Record the current time for later use. */ /* Record the current time for later use. */
LONGLONG start_time = gtod.usecs (); LONGLONG start_time = gtod.msecs ();
select_stuff sel; select_stuff sel;
sel.return_on_signal = 0; sel.return_on_signal = 0;
@ -185,7 +158,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 /* Degenerate case. No fds to wait for. Just wait for time to run out
or signal to arrive. */ or signal to arrive. */
if (sel.start.next == NULL) if (sel.start.next == NULL)
switch (cygwait_us (us)) switch (cygwait (ms))
{ {
case WAIT_SIGNALED: case WAIT_SIGNALED:
select_printf ("signal received"); select_printf ("signal received");
@ -205,12 +178,12 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
wait_state = select_stuff::select_set_zero; wait_state = select_stuff::select_set_zero;
break; break;
} }
else if (sel.always_ready || us == 0) else if (sel.always_ready || ms == 0)
/* Catch any active fds via sel.poll() below */ /* Catch any active fds via sel.poll() below */
wait_state = select_stuff::select_ok; wait_state = select_stuff::select_ok;
else else
/* wait for an fd to become active or time out */ /* wait for an fd to become active or time out */
wait_state = sel.wait (r, w, e, us); wait_state = sel.wait (r, w, e, ms);
select_printf ("sel.wait returns %d", wait_state); select_printf ("sel.wait returns %d", wait_state);
@ -236,11 +209,11 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
sel.cleanup (); sel.cleanup ();
sel.destroy (); sel.destroy ();
/* Recalculate time remaining to wait if we are going to be looping. */ /* Recalculate time remaining to wait if we are going to be looping. */
if (wait_state == select_stuff::select_loop && us != -1) if (wait_state == select_stuff::select_loop && ms != INFINITE)
{ {
select_printf ("recalculating us"); select_printf ("recalculating ms");
LONGLONG now = gtod.usecs (); LONGLONG now = gtod.msecs ();
if (now > (start_time + us)) if (now > (start_time + ms))
{ {
select_printf ("timed out after verification"); select_printf ("timed out after verification");
/* Set descriptor bits to zero per POSIX. */ /* Set descriptor bits to zero per POSIX. */
@ -252,9 +225,9 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
} }
else else
{ {
us -= (now - start_time); ms -= (now - start_time);
start_time = now; start_time = now;
select_printf ("us now %lld", us); select_printf ("ms now %u", ms);
} }
} }
} }
@ -265,6 +238,33 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
return ret; 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 /* Call cleanup functions for all inspected fds. Gets rid of any
executing threads. */ executing threads. */
void void
@ -362,50 +362,13 @@ err:
/* The heart of select. Waits for an fd to do something interesting. */ /* The heart of select. Waits for an fd to do something interesting. */
select_stuff::wait_states select_stuff::wait_states
select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
LONGLONG us) DWORD ms)
{ {
HANDLE w4[MAXIMUM_WAIT_OBJECTS]; HANDLE w4[MAXIMUM_WAIT_OBJECTS];
select_record *s = &start; select_record *s = &start;
DWORD m = 0; DWORD m = 0;
/* Always wait for signals. */
wait_signal_arrived here (w4[m++]); 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) if ((w4[m] = pthread::get_cancel_event ()) != NULL)
m++; m++;
@ -434,27 +397,21 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
next_while:; next_while:;
} }
debug_printf ("m %d, us %llu, dTimeoutMs %d", m, us, dTimeoutMs); debug_printf ("m %d, ms %u", m, ms);
DWORD wait_ret; DWORD wait_ret;
if (!windows_used) if (!windows_used)
wait_ret = WaitForMultipleObjects (m, w4, FALSE, dTimeoutMs); wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
else else
/* Using MWMO_INPUTAVAILABLE is the officially supported solution for /* Using MWMO_INPUTAVAILABLE is the officially supported solution for
the problem that the call to PeekMessage disarms the queue state the problem that the call to PeekMessage disarms the queue state
so that a subsequent MWFMO hangs, even if there are still messages so that a subsequent MWFMO hangs, even if there are still messages
in the queue. */ in the queue. */
wait_ret = MsgWaitForMultipleObjectsEx (m, w4, dTimeoutMs, wait_ret = MsgWaitForMultipleObjectsEx (m, w4, ms,
QS_ALLINPUT | QS_ALLPOSTMESSAGE, QS_ALLINPUT | QS_ALLPOSTMESSAGE,
MWMO_INPUTAVAILABLE); MWMO_INPUTAVAILABLE);
select_printf ("wait_ret %d, m = %d. verifying", wait_ret, m); select_printf ("wait_ret %d, m = %d. verifying", wait_ret, m);
if (dTimeoutMs == INFINITE)
{
CancelWaitableTimer (hTimeout);
CloseHandle (hTimeout);
}
wait_states res; wait_states res;
switch (wait_ret) switch (wait_ret)
{ {
@ -477,13 +434,12 @@ next_while:;
s->set_select_errno (); s->set_select_errno ();
res = select_error; res = select_error;
break; break;
case WAIT_OBJECT_0 + 1:
case WAIT_TIMEOUT: case WAIT_TIMEOUT:
select_printf ("timed out"); select_printf ("timed out");
res = select_set_zero; res = select_set_zero;
break; break;
case WAIT_OBJECT_0 + 2: case WAIT_OBJECT_0 + 1:
if (startfds > 2) if (startfds > 1)
{ {
cleanup (); cleanup ();
destroy (); destroy ();

View File

@ -96,7 +96,7 @@ public:
bool test_and_set (int, fd_set *, fd_set *, fd_set *); bool test_and_set (int, fd_set *, fd_set *, fd_set *);
int poll (fd_set *, fd_set *, fd_set *); int poll (fd_set *, fd_set *, fd_set *);
wait_states wait (fd_set *, fd_set *, fd_set *, LONGLONG); wait_states wait (fd_set *, fd_set *, fd_set *, DWORD);
void cleanup (); void cleanup ();
void destroy (); void destroy ();