module ServerEngine::SocketManagerUnix::ServerModule

Private Instance Methods

listen_tcp_new(bind_ip, port) click to toggle source
# File lib/serverengine/socket_manager_unix.rb, line 52
def listen_tcp_new(bind_ip, port)
  if ENV['SERVERENGINE_USE_SOCKET_REUSEPORT'] == '1'
    # Based on Addrinfo#listen
    tsock = Socket.new(bind_ip.ipv6? ? ::Socket::AF_INET6 : ::Socket::AF_INET, ::Socket::SOCK_STREAM, 0)
    tsock.ipv6only! if bind_ip.ipv6?
    tsock.setsockopt(:SOCKET, :REUSEPORT, true)
    tsock.setsockopt(:SOCKET, :REUSEADDR, true)
    tsock.bind(Addrinfo.tcp(bind_ip.to_s, port))
    tsock.listen(::Socket::SOMAXCONN)
    tsock.autoclose = false
    TCPServer.for_fd(tsock.fileno)
  else
    # TCPServer.new doesn't set IPV6_V6ONLY flag, so use Addrinfo class instead.
    # TODO: make backlog configurable if necessary
    tsock = Addrinfo.tcp(bind_ip.to_s, port).listen(::Socket::SOMAXCONN)
    tsock.autoclose = false
    TCPServer.for_fd(tsock.fileno)
  end
end
listen_udp_new(bind_ip, port) click to toggle source
# File lib/serverengine/socket_manager_unix.rb, line 72
def listen_udp_new(bind_ip, port)
  # UDPSocket.new doesn't set IPV6_V6ONLY flag, so use Addrinfo class instead.
  usock = Addrinfo.udp(bind_ip.to_s, port).bind
  usock.autoclose = false
  UDPSocket.for_fd(usock.fileno)
end
send_socket(peer, pid, method, bind, port) click to toggle source
# File lib/serverengine/socket_manager_unix.rb, line 114
def send_socket(peer, pid, method, bind, port)
  sock = case method
         when :listen_tcp
           listen_tcp(bind, port)
         when :listen_udp
           listen_udp(bind, port)
         else
           raise ArgumentError, "Unknown method: #{method.inspect}"
         end

  SocketManager.send_peer(peer, nil)

  peer.send_io sock
end
start_server(path) click to toggle source
# File lib/serverengine/socket_manager_unix.rb, line 79
def start_server(path)
  # return absolute path so that client can connect to this path
  # when client changed working directory
  path = File.expand_path(path)

  begin
    old_umask = File.umask(0077) # Protect unix socket from other users
    @server = UNIXServer.new(path)
  ensure
    File.umask(old_umask)
  end

  @thread = Thread.new do
    begin
      while peer = @server.accept
        Thread.new(peer, &method(:process_peer))  # process_peer calls send_socket
      end
    rescue => e
      unless @server.closed?
        ServerEngine.dump_uncaught_error(e)
      end
    end
  end

  return path
end
stop_server() click to toggle source
# File lib/serverengine/socket_manager_unix.rb, line 106
def stop_server
  @tcp_sockets.reject! {|key,lsock| lsock.close; true }
  @udp_sockets.reject! {|key,usock| usock.close; true }
  @server.close unless @server.closed?
  # It cause dead lock and can't finish when joining thread using Ruby 2.1 on linux.
  @thread.join if RUBY_VERSION >= "2.2"
end