Project

General

Profile

Bug #2690

IO#select unable to select for < 0.015s

Added by rogerdpack (Roger Pack) almost 10 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Target version:
ruby -v:
ruby 1.9.2dev (2010-01-29) [i386-mingw32]
Backport:
[ruby-core:27957]

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 0; return 1; } #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

History

#1

Updated by rogerdpack (Roger Pack) almost 10 years ago

=begin
I'd be happy to create a patch to use QueryPerformanceCounter if that would be preferable.
-r
=end

#2

Updated by ujihisa (Tatsuhiro Ujihisa) almost 10 years ago

  • Status changed from Open to Assigned
  • Assignee set to nobu (Nobuyoshi Nakada)

=begin

=end

#3

Updated by usa (Usaku NAKAMURA) over 9 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

=begin
This issue was solved with changeset r27930.
Roger, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

=end

#4

Updated by usa (Usaku NAKAMURA) over 9 years ago

  • Status changed from Closed to Assigned
  • Assignee changed from nobu (Nobuyoshi Nakada) to usa (Usaku NAKAMURA)
  • Target version set to 1.9.2

=begin
# should backport to ruby_1_9_2 after some tests,
# so keep this ticket open until next week.
=end

#5

Updated by usa (Usaku NAKAMURA) over 9 years ago

  • Status changed from Assigned to Closed

=begin
yugui had merged on r27975.
=end

Also available in: Atom PDF