16 /* le_callback is allocated at the beginning of the coroutine in which it |
16 /* le_callback is allocated at the beginning of the coroutine in which it |
17 is used, no need to manually de-allocate */ |
17 is used, no need to manually de-allocate */ |
18 |
18 |
19 /* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */ |
19 /* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */ |
20 void luaevent_callback(int fd, short event, void* p) { |
20 void luaevent_callback(int fd, short event, void* p) { |
21 le_callback* arg = p; |
21 le_callback* cb = p; |
22 lua_State* L; |
22 lua_State* L; |
23 int ret; |
23 int ret; |
24 assert(arg && arg->base && arg->base->loop_L); |
24 double newTimeout = -1; |
25 L = arg->base->loop_L; |
25 assert(cb && cb->base && cb->base->loop_L); |
26 lua_rawgeti(L, LUA_REGISTRYINDEX, arg->callbackRef); |
26 L = cb->base->loop_L; |
|
27 lua_rawgeti(L, LUA_REGISTRYINDEX, cb->callbackRef); |
27 lua_pushinteger(L, event); |
28 lua_pushinteger(L, event); |
28 lua_call(L, 1, 1); |
29 lua_call(L, 1, 2); |
29 ret = lua_tointeger(L, -1); |
30 ret = lua_tointeger(L, -2); |
|
31 if(lua_isnumber(L, -1)) { |
|
32 newTimeout = lua_tonumber(L, -1); |
|
33 if(newTimeout <= 0) { |
|
34 memset(&cb->timeout, 0, sizeof(arg->timeout)); |
|
35 } else { |
|
36 load_timeval(newTimeout, &cb->timeout); |
|
37 } |
|
38 } |
30 lua_pop(L, 1); |
39 lua_pop(L, 1); |
31 if(ret == -1) { |
40 if(ret == -1) { |
32 freeCallbackArgs(arg, L); |
41 freeCallbackArgs(cb, L); |
33 } else { |
42 } else { |
34 struct event *ev = &arg->ev; |
43 struct event *ev = &cb->ev; |
35 int newEvent = ret; |
44 int newEvent = ret; |
36 if(newEvent != event) { // Need to hook up new event... |
45 /* NOTE: Currently, even if new timeout is the same as the old, a new event is setup regardless... */ |
|
46 if(newEvent != event || newTimeout != -1) { // Need to hook up new event... |
|
47 struct timeval *ptv = &cb->timeout; |
|
48 if(!cb->timeout.sec && !cb->timeout.usec) |
|
49 ptv = NULL; |
37 event_del(ev); |
50 event_del(ev); |
38 event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, arg); |
51 event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, cb); |
39 event_add(ev, NULL); |
52 /* Assume cannot set a new timeout.. */ |
|
53 event_add(ev, ptv); |
40 } |
54 } |
41 } |
55 } |
42 } |
56 } |
43 |
57 |
44 static int luaevent_cb_gc(lua_State* L) { |
58 static int luaevent_cb_gc(lua_State* L) { |
56 lua_setmetatable(L, -2); |
70 lua_setmetatable(L, -2); |
57 |
71 |
58 lua_pushvalue(L, callbackIdx); |
72 lua_pushvalue(L, callbackIdx); |
59 cb->callbackRef = luaL_ref(L, LUA_REGISTRYINDEX); |
73 cb->callbackRef = luaL_ref(L, LUA_REGISTRYINDEX); |
60 cb->base = base; |
74 cb->base = base; |
|
75 memset(&cb->timeout, 0, sizeof(cb->timeout)); |
61 return cb; |
76 return cb; |
62 } |
77 } |
63 |
78 |
64 int event_callback_register(lua_State* L) { |
79 int event_callback_register(lua_State* L) { |
65 luaL_newmetatable(L, EVENT_CALLBACK_ARG_MT); |
80 luaL_newmetatable(L, EVENT_CALLBACK_ARG_MT); |