Fix LuCId behaviour if thread-limit is reached
authorSteven Barth <steven@midlink.org>
Fri, 10 Jul 2009 13:04:07 +0000 (13:04 +0000)
committerSteven Barth <steven@midlink.org>
Fri, 10 Jul 2009 13:04:07 +0000 (13:04 +0000)
libs/lucid/luasrc/lucid.lua
libs/lucid/luasrc/lucid/tcpserver.lua

index 4963ccc30485b424c014235f986a35b6e0cfb67e..96611d2441890b253284c9c2611876635d578144 100644 (file)
@@ -110,22 +110,25 @@ end
 -- This main function of LuCId will wait for events on given file descriptors.
 function run()
        local pollint = tonumber((cursor:get(UCINAME, "main", "pollinterval")))
-       local threadlimit = tonumber(cursor:get(UCINAME, "main", "threadlimit"))
+       local threadlimit = tonumber((cursor:get(UCINAME, "main", "threadlimit")))
 
        while true do
-               if not threadlimit or tcount < threadlimit then
-                       local stat, code = nixio.poll(pollt, pollint)
+               local stat, code = nixio.poll(pollt, pollint)
                
-                       if stat and stat > 0 then
-                               for _, polle in ipairs(pollt) do
-                                       if polle.revents ~= 0 and polle.handler then
-                                               polle.handler(polle)
-                                       end
+               if stat and stat > 0 then
+                       local ok = false
+                       for _, polle in ipairs(pollt) do
+                               if polle.revents ~= 0 and polle.handler then
+                                       ok = ok or polle.handler(polle)
                                end
-                       elseif stat == 0 then
-                               ifaddrs = nixio.getifaddrs()
-                               collectgarbage("collect")
                        end
+                       if not ok then
+                               -- Avoid high CPU usage if thread limit is reached
+                               nixio.nanosleep(0, 100000000)
+                       end
+               elseif stat == 0 then
+                       ifaddrs = nixio.getifaddrs()
+                       collectgarbage("collect")
                end
                
                for _, cb in ipairs(tickt) do
@@ -200,6 +203,14 @@ function unregister_tick(cb)
        return false
 end
 
+--- Tests whether a given number of processes can be created.
+-- @oaram num Processes to be created
+-- @return boolean status
+function try_process(num)
+       local threadlimit = tonumber((cursor:get(UCINAME, "main", "threadlimit")))
+       return not threadlimit or (threadlimit - tcount) >= (num or 1)
+end
+
 --- Create a new child process from a Lua function and assign a destructor.
 -- @param threadcb main function of the new process
 -- @param waitcb destructor callback
@@ -320,4 +331,4 @@ function daemonize()
        nixio.dup(devnull, nixio.stderr)
        
        return true
-end
+end
\ No newline at end of file
index 2897ec8eaa98da20164107b9a874ff0cd2a3e75a..47748e4a3ebe161cf84326f5ea346c9b2a0fe901 100644 (file)
@@ -111,6 +111,9 @@ end
 -- @param polle Poll descriptor
 -- @return handler process id or nil, error code, error message 
 function accept(polle)
+       if not lucid.try_process() then
+               return false
+       end
        local socket, host, port = polle.fd:accept()
        if not socket then
                return nixio.syslog("warn", "accept() failed: " .. port)