Two performance fixes for HTTP Servers. The first reduces latency from 0.25s to near-zero for back-to-back connections by using the Queue class as a notify system. The second switches the slow socket.get for the much faster socket.read
git-svn-id: file:///home/svn/framework3/trunk@12615 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
543ec2c3a1
commit
aa98667a77
|
@ -1,3 +1,5 @@
|
||||||
|
require 'thread'
|
||||||
|
|
||||||
module Rex
|
module Rex
|
||||||
module IO
|
module IO
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ module StreamServer
|
||||||
#
|
#
|
||||||
def start
|
def start
|
||||||
self.clients = []
|
self.clients = []
|
||||||
|
self.client_waiter = ::Queue.new
|
||||||
|
|
||||||
self.listener_thread = Rex::ThreadFactory.spawn("StreamServerListener", false) {
|
self.listener_thread = Rex::ThreadFactory.spawn("StreamServerListener", false) {
|
||||||
monitor_listener
|
monitor_listener
|
||||||
|
@ -128,6 +131,7 @@ module StreamServer
|
||||||
|
|
||||||
attr_accessor :clients # :nodoc:
|
attr_accessor :clients # :nodoc:
|
||||||
attr_accessor :listener_thread, :clients_thread # :nodoc:
|
attr_accessor :listener_thread, :clients_thread # :nodoc:
|
||||||
|
attr_accessor :client_waiter
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
@ -151,6 +155,9 @@ protected
|
||||||
|
|
||||||
# Initialize the connection processing
|
# Initialize the connection processing
|
||||||
on_client_connect(cli)
|
on_client_connect(cli)
|
||||||
|
|
||||||
|
# Notify the client monitor
|
||||||
|
self.client_waiter.push(cli)
|
||||||
|
|
||||||
# Skip exceptions caused by accept() [ SSL ]
|
# Skip exceptions caused by accept() [ SSL ]
|
||||||
rescue ::EOFError, ::Errno::ECONNRESET, ::Errno::ENOTCONN, ::Errno::ECONNABORTED
|
rescue ::EOFError, ::Errno::ECONNRESET, ::Errno::ENOTCONN, ::Errno::ECONNABORTED
|
||||||
|
@ -170,12 +177,14 @@ protected
|
||||||
#
|
#
|
||||||
def monitor_clients
|
def monitor_clients
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
# Wait for a notify if our client list is empty
|
||||||
if (clients.length == 0)
|
if (clients.length == 0)
|
||||||
Rex::ThreadSafe::sleep(0.25)
|
self.client_waiter.pop
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
sd = Rex::ThreadSafe.select(clients)
|
sd = Rex::ThreadSafe.select(clients, nil, nil, nil)
|
||||||
|
|
||||||
sd[0].each { |cfd|
|
sd[0].each { |cfd|
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -278,7 +278,7 @@ protected
|
||||||
#
|
#
|
||||||
# XXX: Handle ParseCode::Partial
|
# XXX: Handle ParseCode::Partial
|
||||||
#
|
#
|
||||||
data = cli.get
|
data = cli.read(65535)
|
||||||
|
|
||||||
raise ::EOFError if not data
|
raise ::EOFError if not data
|
||||||
raise ::EOFError if data.empty?
|
raise ::EOFError if data.empty?
|
||||||
|
|
Loading…
Reference in New Issue