1 /* LuaEvent - Copyright (C) 2007 Thomas Harning <harningt@gmail.com>
2 * Licensed as LGPL - See doc/COPYING for details */
3 #include "event_callback.h"
8 #define EVENT_CALLBACK_ARG_MT "EVENT_CALLBACK_ARG_MT"
10 void freeCallbackArgs(le_callback
* arg
, lua_State
* L
) {
14 luaL_unref(L
, LUA_REGISTRYINDEX
, arg
->callbackRef
);
17 /* le_callback is allocated at the beginning of the coroutine in which it
18 is used, no need to manually de-allocate */
20 /* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */
21 void luaevent_callback(int fd
, short event
, void* p
) {
25 double newTimeout
= -1;
28 /* Callback has been collected... die */
29 /* TODO: What should really be done here... */
32 assert(cb
->base
->loop_L
);
34 lua_rawgeti(L
, LUA_REGISTRYINDEX
, cb
->callbackRef
);
35 lua_pushinteger(L
, event
);
37 ret
= lua_tointeger(L
, -2);
38 if(lua_isnumber(L
, -1)) {
39 newTimeout
= lua_tonumber(L
, -1);
41 memset(&cb
->timeout
, 0, sizeof(cb
->timeout
));
43 load_timeval(newTimeout
, &cb
->timeout
);
48 freeCallbackArgs(cb
, L
);
50 struct event
*ev
= &cb
->ev
;
52 /* NOTE: Currently, even if new timeout is the same as the old, a new event is setup regardless... */
53 if(newEvent
!= event
|| newTimeout
!= -1) { // Need to hook up new event...
54 struct timeval
*ptv
= &cb
->timeout
;
55 if(!cb
->timeout
.tv_sec
&& !cb
->timeout
.tv_usec
)
58 event_set(ev
, fd
, EV_PERSIST
| newEvent
, luaevent_callback
, cb
);
59 /* Assume cannot set a new timeout.. */
65 static int luaevent_cb_gc(lua_State
* L
) {
66 le_callback
* arg
= luaL_checkudata(L
, 1, EVENT_CALLBACK_ARG_MT
);
67 freeCallbackArgs(arg
, L
);
71 le_callback
* event_callback_push(lua_State
* L
, int baseIdx
, int callbackIdx
) {
73 le_base
*base
= event_base_get(L
, baseIdx
);
74 luaL_checktype(L
, callbackIdx
, LUA_TFUNCTION
);
75 cb
= lua_newuserdata(L
, sizeof(*cb
));
76 luaL_getmetatable(L
, EVENT_CALLBACK_ARG_MT
);
77 lua_setmetatable(L
, -2);
79 lua_pushvalue(L
, callbackIdx
);
80 cb
->callbackRef
= luaL_ref(L
, LUA_REGISTRYINDEX
);
82 memset(&cb
->timeout
, 0, sizeof(cb
->timeout
));
86 int event_callback_register(lua_State
* L
) {
87 luaL_newmetatable(L
, EVENT_CALLBACK_ARG_MT
);
88 lua_pushcfunction(L
, luaevent_cb_gc
);
89 lua_setfield(L
, -2, "__gc");
91 lua_pushcfunction(L
, luaevent_cb_gc
);
92 lua_setfield(L
, -2, "close");
93 lua_setfield(L
, -2, "__index");