--- Starts a new LuCId superprocess.
function start()
+ state:revert(UCINAME, "main")
+
prepare()
local detach = cursor:get(UCINAME, "main", "daemonize")
run()
end
+--- Returns the PID of the currently active LuCId process.
+function running()
+ local pid = tonumber(state:get(UCINAME, "main", "pid"))
+ return pid and nixio.kill(pid, 0) and pid
+end
+
--- Stops any running LuCId superprocess.
function stop()
local pid = tonumber(state:get(UCINAME, "main", "pid"))
-- 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")))
while true do
local stat, code = nixio.poll(pollt, pollint)
if stat and stat > 0 then
+ local ok = false
for _, polle in ipairs(pollt) do
if polle.revents ~= 0 and polle.handler then
- polle.handler(polle)
+ ok = ok or polle.handler(polle)
end
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
local pid, stat, code = nixio.wait(-1, "nohang")
while pid and pid > 0 do
- tcount = tcount - 1
- if tpids[pid] and tpids[pid] ~= true then
- tpids[pid](pid, stat, code)
+ nixio.syslog("info", "Buried thread: " .. pid)
+ if tpids[pid] then
+ tcount = tcount - 1
+ if tpids[pid] ~= true then
+ tpids[pid](pid, stat, code)
+ end
+ tpids[pid] = nil
end
pid, stat, code = nixio.wait(-1, "nohang")
end
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
if threadlimit and tcount >= threadlimit then
nixio.syslog("warning", "Cannot create thread: process limit reached")
return nil
+ else
+ collectgarbage("collect")
end
local pid, code, err = nixio.fork()
if pid and pid ~= 0 then
- tpids[pid] = waitcb
+ nixio.syslog("info", "Created thread: " .. pid)
+ tpids[pid] = waitcb or true
tcount = tcount + 1
elseif pid == 0 then
local code = threadcb()
nixio.dup(devnull, nixio.stderr)
return true
-end
\ No newline at end of file
+end