aboutsummaryrefslogtreecommitdiffstats
path: root/luaevent
diff options
context:
space:
mode:
Diffstat (limited to 'luaevent')
-rw-r--r--luaevent/luaevent.lua54
-rw-r--r--luaevent/src/luaevent.c32
-rw-r--r--luaevent/test/test.lua33
-rw-r--r--luaevent/test/testClient.lua27
4 files changed, 83 insertions, 63 deletions
diff --git a/luaevent/luaevent.lua b/luaevent/luaevent.lua
index 3b8ed18..be7f296 100644
--- a/luaevent/luaevent.lua
+++ b/luaevent/luaevent.lua
@@ -9,18 +9,10 @@ local EV_READ = luaevent.core.EV_READ
local EV_WRITE = luaevent.core.EV_WRITE
local fair = false
--- Weak keys.. the keys are the client sockets
-local clientTable = {} or setmetatable({}, {'__mode', 'k'})
+local hookedObjectMt = false
-local function getWrapper()
- local running = coroutine.running()
- return function(...)
- print(coroutine.running(), running)
- print(debug.traceback())
- if coroutine.running() == running then return end
- return select(2, coroutine.resume(running, ...))
- end
-end
+-- Weak keys.. the keys are the client sockets
+local clientTable = setmetatable({}, {'__mode', 'k'})
function send(sock, data, start, stop)
local s, err
@@ -35,7 +27,6 @@ function send(sock, data, start, stop)
coroutine.yield(EV_WRITE)
end
if s or err ~= "timeout" then return s, err, sent end
- if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_WRITE, getWrapper()) end
coroutine.yield(EV_WRITE)
until false
end
@@ -45,7 +36,6 @@ function receive(sock, pattern, part)
repeat
s, err, part = sock:receive(pattern, part)
if s or err ~= "timeout" then return s, err, part end
- if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_READ, getWrapper()) end
coroutine.yield(EV_READ)
until false
end
@@ -58,7 +48,6 @@ function receivePartial(client, pattern)
s, err, part = client:receive(pattern)
if s or ( (type(pattern)=="number") and part~="" and part ~=nil ) or
err ~= "timeout" then return s, err, part end
- if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_READ, getWrapper()) end
coroutine.yield(EV_READ)
until false
end
@@ -66,7 +55,6 @@ function connect(sock, ...)
sock:settimeout(0)
local ret, err = sock:connect(...)
if ret or err ~= "timeout" then return ret, err end
- if not clientTable[sock] then clientTable[sock] = luaevent.core.addevent(sock, EV_WRITE, getWrapper()) end
coroutine.yield(EV_WRITE)
ret, err = sock:connect(...)
if err == "already connected" then
@@ -81,28 +69,44 @@ local function clientCoroutine(sock, handler)
-- Figure out what to do ......
return handler(sock)
end
-local function handleClient(co, client, handler)
- local ok, res, event = coroutine.resume(co, client, handler)
-end
+
local function serverCoroutine(sock, callback)
- local listenItem = luaevent.core.addevent(sock, EV_READ, getWrapper())
repeat
local event = coroutine.yield(EV_READ)
-- Get new socket
local client = sock:accept()
if client then
+ --cl[#cl + 1] = client
client:settimeout(0)
- local co = coroutine.create(clientCoroutine)
- handleClient(co, client, callback)
+ local coFunc = coroutine.wrap(clientCoroutine)
+ clientTable[client] = luaevent.core.addevent(client, coFunc, client, callback)
end
until false
end
+
+local oldAddEvent = luaevent.core.addevent
+luaevent.core.addevent = function(...)
+ local item = oldAddEvent(...)
+ print("SETUP ITEM FOR: ", debug.getmetatable(item).getfd(item))
+ if not hookedObjectMt then
+ hookedObjectMt = true
+ local mt = debug.getmetatable(item)
+ local oldGC = mt.__gc
+ mt.__gc = function(...)
+ print("RELEASING ITEM FOR: ", mt.getfd(...))
+ return oldGC(...)
+ end
+ end
+ return item
+end
+
function addserver(sock, callback)
- local coro = coroutine.create(serverCoroutine)
- assert(coroutine.resume(coro, sock, callback))
+ local coFunc = coroutine.wrap(serverCoroutine)
+ clientTable[sock] = luaevent.core.addevent(sock, coFunc, sock, callback)
end
-function addthread(func, ...)
- return coroutine.resume(coroutine.create(func), ...)
+function addthread(sock, func, ...)
+ local coFunc = coroutine.wrap(func)
+ clientTable[sock] = luaevent.core.addevent(sock, coFunc, ...)
end
local _skt_mt = {__index = {
connect = function(self, ...)
diff --git a/luaevent/src/luaevent.c b/luaevent/src/luaevent.c
index 311ad0e..d79345e 100644
--- a/luaevent/src/luaevent.c
+++ b/luaevent/src/luaevent.c
@@ -74,6 +74,12 @@ static int luaevent_cb_gc(lua_State* L) {
return 0;
}
+static int luaevent_cb_getfd(lua_State* L) {
+ le_callback* arg = luaL_checkudata(L, 1, EVENT_CALLBACK_ARG_MT);
+ lua_pushinteger(L, arg->ev.ev_fd);
+ return 1;
+}
+
int getSocketFd(lua_State* L, int idx) {
int fd;
luaL_checktype(L, idx, LUA_TUSERDATA);
@@ -90,23 +96,35 @@ int getSocketFd(lua_State* L, int idx) {
/* Expected to be called at the beginning of the coro that uses it..
Value must be kept until coro is complete....
*/
-/* sock, event, callback */
+/* sock, callback */
static int luaevent_addevent(lua_State* L) {
- int fd, event, callbackRef;
+ int fd, callbackRef;
+ int top, ret;
le_callback* arg;
fd = getSocketFd(L, 1);
- event = luaL_checkinteger(L, 2);
- luaL_checktype(L, 3, LUA_TFUNCTION);
- lua_pushvalue(L, 3);
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ top = lua_gettop(L);
+ /* Preserve the callback function */
+ lua_pushvalue(L, 2);
callbackRef = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ /* Call the callback with all arguments after it to get the loop primed.. */
+ lua_call(L, top - 2, 1);
+ ret = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+ if(ret == -1) { /* Done, no need to setup event */
+ luaL_unref(L, LUA_REGISTRYINDEX, callbackRef);
+ return 0;
+ }
arg = lua_newuserdata(L, sizeof(*arg));
luaL_getmetatable(L, EVENT_CALLBACK_ARG_MT);
lua_setmetatable(L, -2);
arg->L = L;
arg->callbackRef = callbackRef;
+
/* Setup event... */
- event_set(&arg->ev, fd, event | EV_PERSIST, luaevent_callback, arg);
+ event_set(&arg->ev, fd, ret | EV_PERSIST, luaevent_callback, arg);
event_base_set(getEventBase(L), &arg->ev);
event_add(&arg->ev, NULL);
return 1;
@@ -157,6 +175,8 @@ int luaopen_luaevent_core(lua_State* L) {
luaL_newmetatable(L, EVENT_CALLBACK_ARG_MT);
lua_pushcfunction(L, luaevent_cb_gc);
lua_setfield(L, -2, "__gc");
+ lua_pushcfunction(L, luaevent_cb_getfd);
+ lua_setfield(L, -2, "getfd");
lua_pop(L, 1);
setEventBase(L, event_init());
diff --git a/luaevent/test/test.lua b/luaevent/test/test.lua
index 1bcd173..f7a44da 100644
--- a/luaevent/test/test.lua
+++ b/luaevent/test/test.lua
@@ -6,29 +6,18 @@
require"luaevent"
require"socket"
local function echoHandler(skt)
- while true do
- print(skt)
- local data,ret = luaevent.receive(skt, 10)
- print("GOT: ", data, ret)
- if data == "quit" or ret == 'closed' then
- break
- end
- luaevent.send(skt, data)
- end
- print("DONE")
-end
-local function setupHook(thread)
- if not thread then debug.sethook(function(event) print("TRACE >: ", debug.getinfo(2, 'n').name) end, 'c')
- else debug.sethook(thread, function(event) print("TRACE ", thread,">: ", debug.getinfo(2, 'n').name) end, 'c') end
+ while true do
+ local data,ret = luaevent.receive(skt, 10)
+ if data == "quit" or ret == 'closed' then
+ break
+ end
+ --collectgarbage()
+ luaevent.send(skt, data)
+ end
end
+
local server = assert(socket.bind("localhost", 20000))
server:settimeout(0)
-setupHook()
-local coro = coroutine.create
-coroutine.create = function(...)
- local ret = coro(...)
- setupHook(ret)
- return ret
-end
+
luaevent.addserver(server, echoHandler)
-luaevent.loop()
+luaevent.loop() \ No newline at end of file
diff --git a/luaevent/test/testClient.lua b/luaevent/test/testClient.lua
index b6dfa44..0557230 100644
--- a/luaevent/test/testClient.lua
+++ b/luaevent/test/testClient.lua
@@ -1,15 +1,22 @@
require"luaevent"
require"socket"
+local function setupHook(thread)
+ if not thread then debug.sethook(function(event) print("TRACE >: ", debug.getinfo(2, 'n').name) end, 'c')
+ else debug.sethook(thread, function(event) print("TRACE ", thread,">: ", debug.getinfo(2, 'n').name) end, 'c') end
+end
-local function func()
- print("ACTIVATED")
- local sock = socket.tcp()
- --sock:
+local function func(sock)
sock = luaevent.wrap(sock)
- print(assert(sock:connect("localhost", 20000)))
- for i = 1, 100000 do assert(sock:send("Greet me ")) assert(sock:receive(10)) collectgarbage() end
+ assert(sock:connect("localhost", 20000))
+ for i = 1, 10 do
+ for z = 1, 100 do
+ assert(sock:send("Greet me "))
+ end
+ assert(sock:receive(10 * 100))
+ end
end
-
-luaevent.addthread(func)
-
-luaevent.loop() \ No newline at end of file
+for i = 1, 1020 do
+ local sock = assert(socket.tcp())
+ luaevent.addthread(sock, func, sock)
+end
+luaevent.loop()