class Diameter::Internals::StackHelper

@private

Public Class Methods

new(stack) click to toggle source
# File lib/diameter/stack_transport_helpers.rb, line 14
def initialize(stack)
  @all_connections = []
  @listen_connections = []
  @data = {}
  @stack = stack
  @loop_thread = nil
  @accept_loop_thread = nil
  @connection_lock = Mutex.new
  @wakeup_pipe_rd, @wakeup_pipe_wr = IO.pipe
end

Public Instance Methods

main_loop() click to toggle source
# File lib/diameter/stack_transport_helpers.rb, line 47
def main_loop
    rs, _ws, es = IO.select(@all_connections + [@wakeup_pipe_rd], [], @all_connections)

  es.each do |e|
    # :nocov:
    Diameter.logger.log(Logger::WARN, "Exception on connection #{e}")
    # :nocov:
  end

  rs.each do |r|
    if r == @wakeup_pipe_rd
      r.gets
      next
    end

    existing_data = @data[r]
    if existing_data.length < 4
      msg, _src = read_from(r, 4 - existing_data.length)
      existing_data += msg
    end

    expected_len = -1
    if existing_data.length >= 4
      expected_len = Message.length_from_header(existing_data[0..4])
      Diameter.logger.debug("Read 4 bytes #{existing_data[0..4].inspect}, " \
                            "reading full message of length #{expected_len}")
      msg, _src = read_from(r, expected_len - existing_data.length)
      existing_data += msg
    end

    if existing_data.length == expected_len
      @stack.handle_message(existing_data, r)
      @data[r] = ''
    else
      @data[r] = existing_data
    end
  end
end
read_from(connection, bytes) click to toggle source
# File lib/diameter/stack_transport_helpers.rb, line 38
def read_from(connection, bytes)
  msg, src = connection.recv_nonblock(bytes)
  if msg == ''
    Diameter.logger.warn('Received 0 bytes on read, closing connection')
    close(connection)
  end
  return msg, src
end
send(bytes, connection) click to toggle source
# File lib/diameter/stack_transport_helpers.rb, line 86
def send(bytes, connection)
  connection.send(bytes, 0)
end
start_main_loop() click to toggle source
# File lib/diameter/stack_transport_helpers.rb, line 25
def start_main_loop
  @loop_thread = Thread.new do
    loop do
      main_loop
    end
  end
  @loop_thread.abort_on_exception = true
end
wakeup() click to toggle source
# File lib/diameter/stack_transport_helpers.rb, line 34
def wakeup
  @wakeup_pipe_wr.puts "wakeup"
end