Bug #2690
closedIO#select unable to select for < 0.015s
Description
=begin
In my investigation related to the previous "cannot select for < 0.10s on windows" but, here is the current situation (in windows).
This code, run with 1.9.2 trunk:
require 'benchmark'
a = TCPSocket.new('google.com', 80)
puts Benchmark.realtime { 10.times { IO.select([a], nil, nil, 0) } }
always outputs 0.15s (expected to output much less--1.8 outputs 0)
What is happening is that within select, the subtract(timeval, timeval) method is not accomodating for timeval's that are equal. We are using GetSystemTimeAsFileTime for gettimeofday, its resolution is 15ms[1], which means that for the first 15ms, gettimeofday is returning equal time stamps, and select is looping doing select over and over again, for 0.015s per select.
Allowing subtract to accomodate for the same timestamp seems to fix the problem.
Another option would be to use QueryPerformanceCounter instead of GetSystemTimeAsFileTime[1]. You'll notice also that Time.now (and Benchmark.realtime, etc.) have increments of 0.015s, etc. but accomodating for this would be a bit more involved, and perhaps material for another, separate patch (I...think subtract should by default accomodate for equal values, anyway, even in linux, so this patch is still good, either way).
Thanks for your consideration.
-rp
[1] http://msdn.microsoft.com/en-us/magazine/cc163996.aspx
Index: thread.c¶
--- thread.c (revision 26462)
+++ thread.c (working copy)
@@ -2403,6 +2403,8 @@
}
rest->tv_sec -= wait->tv_sec;
rest->tv_usec -= wait->tv_usec;
- if(rest->tv_sec == 0 && rest->tv_usec == 0)
-
return 1;return 0;
}
#endif
Index: win32/win32.c
===================================================================
--- win32/win32.c (revision 26462)
+++ win32/win32.c (working copy)
@@ -2389,6 +2389,9 @@
}
rest->tv_sec -= wait->tv_sec;
rest->tv_usec -= wait->tv_usec; - if(rest->tv_sec == 0 && rest->tv_usec == 0)
-
return 0;
- return 1;
}
=end