3 HTTP server implementation for LuCI - core
4 (c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
5 (c) 2008 Steven Barth <steven@midlink.org>
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
17 module("luci.httpd", package.seeall)
20 THREAD_IDLEWAIT = 0.01
33 local _meta = {__mode = "k"}
34 setmetatable(threads, _meta)
35 setmetatable(threadm, _meta)
36 setmetatable(threadi, _meta)
39 function Socket(ip, port)
40 local sock, err = socket.bind( ip, port )
43 sock:settimeout( 0, "t" )
49 function corecv(socket, ...)
50 threadi[socket] = true
53 local chunk, err, part = socket:receive(...)
55 if err ~= "timeout" then
56 threadi[socket] = false
57 return chunk, err, part
64 function cosend(socket, chunk, i, ...)
65 threadi[socket] = true
69 local stat, err, sent = socket:send(chunk, i, ...)
71 if err ~= "timeout" then
72 threadi[socket] = false
73 return stat, err, sent
75 i = sent and (sent + 1) or i
82 function register(socket, s_clhandler, s_errhandler)
83 table.insert(reading, socket)
84 clhandler[socket] = s_clhandler
85 erhandler[socket] = s_errhandler
95 print(collectgarbage("count"))
97 if not THREAD_LIMIT or threadc < THREAD_LIMIT then
99 for i, server in ipairs(reading) do
100 local client = server:accept()
102 threadm[client] = now
103 threadc = threadc + 1
104 threads[client] = coroutine.create(clhandler[server])
109 for client, thread in pairs(threads) do
110 coroutine.resume(thread, client)
111 local now = os.time()
112 if coroutine.status(thread) == "dead" then
113 threadc = threadc - 1
114 elseif threadm[client] and threadm[client] + THREAD_TIMEOUT < now then
115 threads[client] = nil
116 threadc = threadc - 1
118 elseif not threadi[client] then
119 threadm[client] = now
125 socket.sleep(THREAD_IDLEWAIT)