In my last post I talked about patching LuaSocket to make it work with LuaLanes. The patch is there: lua socket acceptfd patch.
So what does it do?
It adds a new method “acceptfd” which works just like “accept” but instead of returning a socket object it returns the underlying “file descriptor” (a number). A new optional parameter to “socket.tcp()” allows to create a socket object from a file descriptor.
How does it help us ?
Lua Lanes handles multithreading by running a new lua state in each thread, they do not share data and instead communicate using Lindas (see the docs on Lanes site). Linda is great but it cannot pass such userdatas as sockets. Si we use this patch to accept an incomming connection, getting its file descriptor. Then pass it onto a new thread which creates its socket object from it.
Easy, fast and grooovy!
A little exemple:
require ‘lanes’
require ’socket’local linda = lanes.linda()
function handler(fd)
require’socket’local sock = socket.tcp(fd)
local line = sock:receive(”*l”)
linda:send(”order”, {line=line})
sock:send(”line: “..tostring(line)..” \n”)
sock:close()
return “done”
endfunction main_thread()
while true do
local order = linda:receive(3, “order”)
if order then
print(”order”, order.line)
end
end
endfunction run()
local s = socket.bind(”0.0.0.0″, 2525)
local threads = {}lanes.gen(”*”, main_thread)()
while true do
local fd = s:acceptfd()
threads[lanes.gen("*", handler)(fd)] = fdprint(”threads:”)
for h, s in pairs(threads) do
print(” * “, h, ” :=: “, h.status)local v, err = h:join(0)
if not v and err then
print(err)
elseif v and v == “done” then
threads[h] = nil
end
end
end
endrun()
(Badly formated sorry, I have not yet mastered the art of posting code with wordpress
)