mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* win32/win32.c (rb_w32_select): recalc the rest of timeout for each
iterations. [ruby-core:18015] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18262 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
be9994a03a
commit
807fcf9d13
4 changed files with 69 additions and 13 deletions
|
@ -1,3 +1,8 @@
|
|||
Wed Jul 30 17:48:15 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* win32/win32.c (rb_w32_select): recalc the rest of timeout for each
|
||||
iterations. [ruby-core:18015]
|
||||
|
||||
Tue Jul 29 23:37:37 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
||||
|
||||
* io.c (io_ungetc): raise NotImplementedError when ungetc is called
|
||||
|
|
10
test/ruby/test_sleep.rb
Normal file
10
test/ruby/test_sleep.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
require 'test/unit'
|
||||
|
||||
class TestSleep < Test::Unit::TestCase
|
||||
def test_sleep_5sec
|
||||
start = Time.now
|
||||
sleep 5
|
||||
slept = Time.now-start
|
||||
assert_in_delta(5.0, slept, 0.1, "[ruby-core:18015]: longer than expected")
|
||||
end
|
||||
end
|
29
thread.c
29
thread.c
|
@ -1957,7 +1957,7 @@ cmp_tv(const struct timeval *a, const struct timeval *b)
|
|||
}
|
||||
|
||||
static int
|
||||
subst(struct timeval *rest, const struct timeval *wait)
|
||||
subtract_tv(struct timeval *rest, const struct timeval *wait)
|
||||
{
|
||||
while (rest->tv_usec < wait->tv_usec) {
|
||||
if (rest->tv_sec <= wait->tv_sec) {
|
||||
|
@ -1982,10 +1982,18 @@ do_select(int n, fd_set *read, fd_set *write, fd_set *except,
|
|||
#ifndef linux
|
||||
double limit = 0;
|
||||
struct timeval wait_rest;
|
||||
# if defined(__CYGWIN__) || defined(_WIN32)
|
||||
struct timeval start_time;
|
||||
# endif
|
||||
|
||||
if (timeout) {
|
||||
limit = timeofday() +
|
||||
(double)timeout->tv_sec+(double)timeout->tv_usec*1e-6;
|
||||
# if defined(__CYGWIN__) || defined(_WIN32)
|
||||
gettimeofday(&start_time, NULL);
|
||||
limit = (double)start_time.tv_sec + (double)start_time.tv_usec*1e-6;
|
||||
# else
|
||||
limit = timeofday();
|
||||
# endif
|
||||
limit += (double)timeout->tv_sec+(double)timeout->tv_usec*1e-6;
|
||||
wait_rest = *timeout;
|
||||
timeout = &wait_rest;
|
||||
}
|
||||
|
@ -2000,6 +2008,7 @@ do_select(int n, fd_set *read, fd_set *write, fd_set *except,
|
|||
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
{
|
||||
int finish = 0;
|
||||
/* polling duration: 100ms */
|
||||
struct timeval wait_100ms, *wait;
|
||||
wait_100ms.tv_sec = 0;
|
||||
|
@ -2017,9 +2026,19 @@ do_select(int n, fd_set *read, fd_set *write, fd_set *except,
|
|||
if (write) *write = orig_write;
|
||||
if (except) *except = orig_except;
|
||||
wait = &wait_100ms;
|
||||
} while (__th->interrupt_flag == 0 && (timeout == 0 || subst(timeout, &wait_100ms)));
|
||||
if (timeout) {
|
||||
struct timeval elapsed;
|
||||
gettimeofday(&elapsed, NULL);
|
||||
subtract_tv(&elapsed, &start_time);
|
||||
if (!subtract_tv(timeout, &elapsed)) {
|
||||
finish = 1;
|
||||
break;
|
||||
}
|
||||
if (cmp_tv(&wait_100ms, timeout) < 0) wait = timeout;
|
||||
}
|
||||
} while (__th->interrupt_flag == 0);
|
||||
}, 0, 0);
|
||||
} while (result == 0 && (timeout == 0 || subst(timeout, &wait_100ms)));
|
||||
} while (result == 0 && !finish);
|
||||
}
|
||||
#else
|
||||
BLOCKING_REGION({
|
||||
|
|
|
@ -2143,7 +2143,7 @@ do_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
|||
}
|
||||
|
||||
static inline int
|
||||
subst(struct timeval *rest, const struct timeval *wait)
|
||||
subtract(struct timeval *rest, const struct timeval *wait)
|
||||
{
|
||||
while (rest->tv_usec < wait->tv_usec) {
|
||||
if (rest->tv_sec <= wait->tv_sec) {
|
||||
|
@ -2174,7 +2174,7 @@ compare(const struct timeval *t1, const struct timeval *t2)
|
|||
#undef Sleep
|
||||
int WSAAPI
|
||||
rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
||||
struct timeval *timeout)
|
||||
struct timeval *timeout)
|
||||
{
|
||||
int r;
|
||||
fd_set pipe_rd;
|
||||
|
@ -2183,11 +2183,29 @@ rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
|||
fd_set else_wr;
|
||||
fd_set except;
|
||||
int nonsock = 0;
|
||||
struct timeval limit;
|
||||
|
||||
if (nfds < 0 || (timeout && (timeout->tv_sec < 0 || timeout->tv_usec < 0))) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
if (timeout->tv_sec < 0 ||
|
||||
timeout->tv_usec < 0 ||
|
||||
timeout->tv_usec >= 1000000) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
gettimeofday(&limit, NULL);
|
||||
limit.tv_sec += timeout->tv_sec;
|
||||
limit.tv_usec += timeout->tv_usec;
|
||||
if (limit.tv_usec >= 1000000) {
|
||||
limit.tv_usec -= 1000000;
|
||||
limit.tv_sec++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NtSocketsInitialized) {
|
||||
StartSockets();
|
||||
}
|
||||
|
@ -2223,10 +2241,9 @@ rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
|||
struct timeval rest;
|
||||
struct timeval wait;
|
||||
struct timeval zero;
|
||||
if (timeout) rest = *timeout;
|
||||
wait.tv_sec = 0; wait.tv_usec = 10 * 1000; // 10ms
|
||||
zero.tv_sec = 0; zero.tv_usec = 0; // 0ms
|
||||
do {
|
||||
for (;;) {
|
||||
if (nonsock) {
|
||||
// modifying {else,pipe,cons}_rd is safe because
|
||||
// if they are modified, function returns immediately.
|
||||
|
@ -2242,8 +2259,7 @@ rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
|||
break;
|
||||
}
|
||||
else {
|
||||
struct timeval *dowait =
|
||||
compare(&rest, &wait) < 0 ? &rest : &wait;
|
||||
struct timeval *dowait = &wait;
|
||||
|
||||
fd_set orig_rd;
|
||||
fd_set orig_wr;
|
||||
|
@ -2257,10 +2273,16 @@ rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
|||
if (wr) *wr = orig_wr;
|
||||
if (ex) *ex = orig_ex;
|
||||
|
||||
// XXX: should check the time select spent
|
||||
if (timeout) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
rest = limit;
|
||||
if (!subtract(&rest, &now)) break;
|
||||
if (compare(&rest, &wait) < 0) dowait = &rest;
|
||||
}
|
||||
Sleep(dowait->tv_sec * 1000 + dowait->tv_usec / 1000);
|
||||
}
|
||||
} while (!timeout || subst(&rest, &wait));
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue