* libs/httpd: Optimized performance

This commit is contained in:
Steven Barth 2008-06-25 18:09:53 +00:00
parent 741bbe7817
commit e0e4983130
2 changed files with 50 additions and 33 deletions

View file

@ -89,7 +89,7 @@ end
function contains(table, value) function contains(table, value)
for k, v in pairs(table) do for k, v in pairs(table) do
if value == v then if value == v then
return true return k
end end
end end
return false return false

View file

@ -61,8 +61,8 @@ function Thread.resume(self, ...)
return coroutine.resume(self.routine, self, ...) return coroutine.resume(self.routine, self, ...)
end end
function Thread.status(self) function Thread.isdead(self)
return coroutine.status(self.routine) return coroutine.status(self.routine) == "dead"
end end
function Thread.touch(self) function Thread.touch(self)
@ -86,6 +86,27 @@ function Daemon.__init__(self, threadlimit, waittime, timeout)
self.timeout = timeout or 90 self.timeout = timeout or 90
end end
function Daemon.remove_dead(self, thread)
if self.debug then
self:dprint("Completed " .. tostring(thread))
end
thread.socket:close()
self.threadc = self.threadc - 1
self.threads[thread.socket] = nil
end
function Daemon.kill_timedout(self)
local now = os.time()
for k, v in pairs(self.threads) do
if os.difftime(now, thread:touched()) > self.timeout then
self.threads[sock] = nil
self.threadc = self.threadc - 1
sock:close()
end
end
end
function Daemon.dprint(self, msg) function Daemon.dprint(self, msg)
if self.debug then if self.debug then
io.stderr:write("[daemon] " .. msg .. "\n") io.stderr:write("[daemon] " .. msg .. "\n")
@ -130,6 +151,8 @@ function Daemon.step(self)
-- reject client -- reject client
else else
self:kill_timedout()
if self.debug then if self.debug then
self:dprint("Rejected incoming connection from " .. sock:getpeername()) self:dprint("Rejected incoming connection from " .. sock:getpeername())
end end
@ -145,34 +168,22 @@ function Daemon.step(self)
-- create client handler -- create client handler
for sock, thread in pairs( self.threads ) do for sock, thread in pairs( self.threads ) do
local now = os.time()
-- reap dead clients
if thread:status() == "dead" then
if self.debug then
self:dprint("Completed " .. tostring(thread))
end
sock:close()
self.threadc = self.threadc - 1
self.threads[sock] = nil
elseif os.difftime(now, thread:touched()) > self.timeout then
self.threads[sock] = nil
sock:close()
-- resume working threads -- resume working threads
elseif not thread:iswaiting() then if not thread:iswaiting() then
if self.debug then if self.debug then
self:dprint("Resuming " .. tostring(thread)) self:dprint("Resuming " .. tostring(thread))
end end
local stat, err = thread:resume() local stat, err = thread:resume()
if stat then if stat and not thread:isdead() then
thread:touch() thread:touch()
if not thread:iswaiting() then if not thread:iswaiting() then
working = true working = true
else else
table.insert(self.waiting, sock) table.insert(self.waiting, sock)
end end
else
self:remove_dead(thread)
end end
if self.debug then if self.debug then
@ -188,10 +199,14 @@ function Daemon.step(self)
input, output, err = socket.select( self.waiting, nil, 0 ) input, output, err = socket.select( self.waiting, nil, 0 )
for i, sock in ipairs(input) do for i, sock in ipairs(input) do
self.threads[sock]:resume() local thread = self.threads[sock]
self.threads[sock]:touch() thread:resume()
if thread:isdead() then
self:remove_dead(thread)
else
thread:touch()
if not self.threads[sock]:iswaiting() then if not thread:iswaiting() then
for i, s in ipairs(self.waiting) do for i, s in ipairs(self.waiting) do
if s == sock then if s == sock then
table.remove(self.waiting, i) table.remove(self.waiting, i)
@ -203,8 +218,10 @@ function Daemon.step(self)
end end
end end
end end
end
if err == "timeout" and not working then if err == "timeout" and not working then
self:kill_timedout()
socket.sleep(self.waittime) socket.sleep(self.waittime)
end end
end end