From e0e498313064c9664d5f86d336d87233ec2792a5 Mon Sep 17 00:00:00 2001 From: Steven Barth Date: Wed, 25 Jun 2008 18:09:53 +0000 Subject: [PATCH] * libs/httpd: Optimized performance --- libs/core/luasrc/util.lua | 4 +-- libs/httpd/luasrc/httpd.lua | 79 +++++++++++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/libs/core/luasrc/util.lua b/libs/core/luasrc/util.lua index e227fc730..9f1d050e7 100644 --- a/libs/core/luasrc/util.lua +++ b/libs/core/luasrc/util.lua @@ -87,9 +87,9 @@ end -- Checks whether a table has an object "value" in it function contains(table, value) - for k,v in pairs(table) do + for k, v in pairs(table) do if value == v then - return true + return k end end return false diff --git a/libs/httpd/luasrc/httpd.lua b/libs/httpd/luasrc/httpd.lua index 9eaa9a68d..050e03ec2 100644 --- a/libs/httpd/luasrc/httpd.lua +++ b/libs/httpd/luasrc/httpd.lua @@ -61,8 +61,8 @@ function Thread.resume(self, ...) return coroutine.resume(self.routine, self, ...) end -function Thread.status(self) - return coroutine.status(self.routine) +function Thread.isdead(self) + return coroutine.status(self.routine) == "dead" end function Thread.touch(self) @@ -86,6 +86,27 @@ function Daemon.__init__(self, threadlimit, waittime, timeout) self.timeout = timeout or 90 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) if self.debug then io.stderr:write("[daemon] " .. msg .. "\n") @@ -130,6 +151,8 @@ function Daemon.step(self) -- reject client else + self:kill_timedout() + if self.debug then self:dprint("Rejected incoming connection from " .. sock:getpeername()) end @@ -144,35 +167,23 @@ function Daemon.step(self) end -- create client handler - 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() + for sock, thread in pairs( self.threads ) do -- resume working threads - elseif not thread:iswaiting() then + if not thread:iswaiting() then if self.debug then self:dprint("Resuming " .. tostring(thread)) end local stat, err = thread:resume() - if stat then + if stat and not thread:isdead() then thread:touch() if not thread:iswaiting() then working = true else table.insert(self.waiting, sock) end + else + self:remove_dead(thread) end if self.debug then @@ -187,24 +198,30 @@ function Daemon.step(self) -- check for data on waiting threads input, output, err = socket.select( self.waiting, nil, 0 ) - for i, sock in ipairs(input) do - self.threads[sock]:resume() - self.threads[sock]:touch() - - if not self.threads[sock]:iswaiting() then - for i, s in ipairs(self.waiting) do - if s == sock then - table.remove(self.waiting, i) - break + for i, sock in ipairs(input) do + local thread = self.threads[sock] + thread:resume() + if thread:isdead() then + self:remove_dead(thread) + else + thread:touch() + + if not thread:iswaiting() then + for i, s in ipairs(self.waiting) do + if s == sock then + table.remove(self.waiting, i) + break + end + end + if not working then + working = true end - end - if not working then - working = true end end end if err == "timeout" and not working then + self:kill_timedout() socket.sleep(self.waittime) end end -- 2.11.0