Method: IO.fast_select
- Defined in:
- lib/openc3/core_ext/io.rb
.fast_select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil) ⇒ Object
On Windows the IO.select function (when called with no timeout) takes a minimum of 10 msec to return, even if one of the IO objects is ready to read/write sooner than that.
This method is identical to IO.select but instead of calling IO.select with the full timeout, it calls IO.select with a small timeout and then doubles the timeout twice until eventually it calls IO.select with the remaining passed in timeout value.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/openc3/core_ext/io.rb', line 53 def fast_select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil) # Always try a zero timeout first current_timeout = SELECT_BASE_TIMEOUT total_timeout = 0.0 while true begin result = IO.__select__(read_sockets, write_sockets, error_array, current_timeout) # All OS errors are subclassed to SystemCallError as Errno::<Subclass> # See https://ruby-doc.org/core-3.1.0/Errno.html rescue SystemCallError return nil end return result if result or current_timeout.nil? return nil if timeout and total_timeout >= timeout if current_timeout <= 0.0001 # Always try the base timeout next current_timeout = SELECT_BASE_TIMEOUT total_timeout = SELECT_BASE_TIMEOUT else # Then start doubling the timeout current_timeout = current_timeout * 2 # Until it is bigger than our max timeout if current_timeout >= SELECT_MAX_TIMEOUT if timeout # Block for the remaining requested timeout current_timeout = timeout - total_timeout total_timeout = timeout else # Or block forever current_timeout = nil end else # Or it is bigger than the given timeout if timeout and current_timeout >= timeout # Block for the remaining requested timeout current_timeout = timeout - total_timeout total_timeout = timeout else # Up our total time in select total_timeout += current_timeout end if timeout and total_timeout > timeout # Block for the remaining requested timeout current_timeout = timeout - total_timeout total_timeout = timeout end end return nil if current_timeout and current_timeout < 0 end end # while true end |