* libs/httpd: Fixed garbage collection
[project/luci.git] / libs / httpd / luasrc / httpd.lua
index 201ece616bdebaa96ee901a34a5a6f2385ee5b84..541063cc7e21cf16c6132076d75e76fb868b3615 100644 (file)
@@ -30,6 +30,11 @@ local threads = {}
 local threadm = {}
 local threadi = {}
 
+local _meta = {__mode = "k"}
+setmetatable(threadm, _meta)
+setmetatable(threadi, _meta)
+
+
 function Socket(ip, port)
        local sock, err = socket.bind( ip, port )
 
@@ -55,6 +60,24 @@ function corecv(socket, ...)
        end
 end
 
+function cosend(socket, chunk, i, ...)
+       threadi[socket] = true
+       i = i or 1
+
+       while true do
+               local stat, err, sent = socket:send(chunk, i, ...)
+
+               if err ~= "timeout" then
+                       threadi[socket] = false
+                       return stat, err, sent
+               else
+                       i = sent and (sent + 1) or i
+               end
+               coroutine.yield()
+       end
+end
+
 function register(socket, s_clhandler, s_errhandler)
        table.insert(reading, socket)
        clhandler[socket] = s_clhandler
@@ -69,7 +92,6 @@ end
 
 function step()
        local idle = true
-               
        if not THREAD_LIMIT or threadc < THREAD_LIMIT then
                local now = os.time()
                for i, server in ipairs(reading) do
@@ -86,8 +108,8 @@ function step()
                coroutine.resume(thread, client)
                local now = os.time()
                if coroutine.status(thread) == "dead" then
-                       threads[client] = nil
                        threadc = threadc - 1
+                       threads[client] = nil
                elseif threadm[client] and threadm[client] + THREAD_TIMEOUT < now then
                        threads[client] = nil
                        threadc = threadc - 1   
@@ -99,6 +121,7 @@ function step()
        end
        
        if idle then
+               collectgarbage()
                socket.sleep(THREAD_IDLEWAIT)
        end
-end
\ No newline at end of file
+end