summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-03 19:46:23 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-03 19:46:23 +0000
commitc98501e706717a41db2465fa020f39dea44d1c5b (patch)
tree914132b01f11878da15c01357a627692c56312a6 /win32
parent202ac43838852cfb15a163e46861e0b49b66926b (diff)
merge revision(s) 18262:
* 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/branches/ruby_1_8_7@21290 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/win32/win32.c b/win32/win32.c
index 8b65360328..498c4b306c 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -2177,7 +2177,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) {
@@ -2207,8 +2207,8 @@ compare(const struct timeval *t1, const struct timeval *t2)
#undef Sleep
long
-rb_w32_select (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
- struct timeval *timeout)
+rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
+ struct timeval *timeout)
{
long r;
fd_set pipe_rd;
@@ -2216,11 +2216,29 @@ rb_w32_select (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
fd_set else_rd;
fd_set else_wr;
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();
}
@@ -2253,10 +2271,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.
@@ -2272,8 +2289,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;
@@ -2287,10 +2303,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;