Class: IO

Inherits:
Object show all
Includes:
OpenC3IO
Defined in:
lib/openc3/core_ext/io.rb

Constant Summary collapse

SELECT_BASE_TIMEOUT =

Initial timeout to call IO.select with. Timeouts are increased by doubling this value until the SELET_MAX_TIMEOUT value is reached.

0.0004
SELECT_MAX_TIMEOUT =

The maximum timeout at which point we call IO.select with whatever remaining timeout is left.

0.016

Class Method Summary collapse

Instance Method Summary collapse

Methods included from OpenC3IO

#read_length_bytes

Class Method Details

.__select__Object

Alias the original IO.select method



38
# File 'lib/openc3/core_ext/io.rb', line 38

alias_method :__select__, :select

.fast_read_select(read_sockets, timeout) ⇒ Object

Parameters:

  • read_sockets (Array<IO>)

    IO objects to wait to be ready to read

  • timeout (Numeric)

    Number of seconds to wait



118
119
120
# File 'lib/openc3/core_ext/io.rb', line 118

def fast_read_select(read_sockets, timeout)
  return fast_select(read_sockets, nil, nil, timeout)
end

.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.

Parameters:

  • read_sockets (Array<IO>) (defaults to: nil)

    IO objects to wait to be ready to read

  • write_sockets (Array<IO>) (defaults to: nil)

    IO objects to wait to be ready to write

  • error_array (Array<IO>) (defaults to: nil)

    IO objects to wait for exceptions

  • timeout (Numeric) (defaults to: nil)

    Number of seconds to wait



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

.fast_write_select(write_sockets, timeout) ⇒ Object

Parameters:

  • write_sockets (Array<IO>)

    IO objects to wait to be ready to write

  • timeout (Numeric)

    Number of seconds to wait



124
125
126
# File 'lib/openc3/core_ext/io.rb', line 124

def fast_write_select(write_sockets, timeout)
  return fast_select(nil, write_sockets, nil, timeout)
end

Instance Method Details

#__close__Object

Alias the original close method



130
# File 'lib/openc3/core_ext/io.rb', line 130

alias_method :__close__, :close

#closeObject

Patch the close method so that it won’t raise any exceptions



133
134
135
136
# File 'lib/openc3/core_ext/io.rb', line 133

def close
  __close__
rescue
end

#select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil) ⇒ Object



111
112
113
# File 'lib/openc3/core_ext/io.rb', line 111

def select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil)
  return fast_select(read_sockets, write_sockets, error_array, timeout)
end