src/event_callback.c

changeset 20
71bc2e49366c
child 21
728aafac9682
equal deleted inserted replaced
19:cbaa6e6ef285 20:71bc2e49366c
1 #include "event_callback.h"
2 #include <assert.h>
3 #include <lauxlib.h>
4
5 void freeCallbackArgs(le_callback* arg, lua_State* L) {
6 if(arg->base) {
7 arg->base = NULL;
8 event_del(&arg->ev);
9 luaL_unref(L, LUA_REGISTRYINDEX, arg->callbackRef);
10 }
11 }
12 /* le_callback is allocated at the beginning of the coroutine in which it
13 is used, no need to manually de-allocate */
14
15 /* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */
16 void luaevent_callback(int fd, short event, void* p) {
17 le_callback* arg = p;
18 lua_State* L;
19 int ret;
20 assert(arg && arg->base && arg->base->loop_L);
21 L = arg->base->loop_L;
22 lua_rawgeti(L, LUA_REGISTRYINDEX, arg->callbackRef);
23 lua_pushinteger(L, event);
24 lua_call(L, 1, 1);
25 ret = lua_tointeger(L, -1);
26 lua_pop(L, 1);
27 if(ret == -1) {
28 freeCallbackArgs(arg, L);
29 } else {
30 struct event *ev = &arg->ev;
31 int newEvent = ret;
32 if(newEvent != event) { // Need to hook up new event...
33 event_del(ev);
34 event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, arg);
35 event_add(ev, NULL);
36 }
37 }
38 }
39
40 static int luaevent_cb_gc(lua_State* L) {
41 le_callback* arg = luaL_checkudata(L, 1, EVENT_CALLBACK_ARG_MT);
42 freeCallbackArgs(arg, L);
43 return 0;
44 }
45
46 int event_callback_register(lua_State* L) {
47 luaL_newmetatable(L, EVENT_CALLBACK_ARG_MT);
48 lua_pushcfunction(L, luaevent_cb_gc);
49 lua_setfield(L, -2, "__gc");
50 lua_newtable(L);
51 lua_pushcfunction(L, luaevent_cb_gc);
52 lua_setfield(L, -2, "close");
53 lua_setfield(L, -2, "__index");
54 lua_pop(L, 1);
55 return 0;
56 }

mercurial