diff -r cbaa6e6ef285 -r 71bc2e49366c src/event_callback.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/event_callback.c Wed Sep 05 22:48:49 2007 -0400 @@ -0,0 +1,56 @@ +#include "event_callback.h" +#include +#include + +void freeCallbackArgs(le_callback* arg, lua_State* L) { + if(arg->base) { + arg->base = NULL; + event_del(&arg->ev); + luaL_unref(L, LUA_REGISTRYINDEX, arg->callbackRef); + } +} +/* le_callback is allocated at the beginning of the coroutine in which it +is used, no need to manually de-allocate */ + +/* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */ +void luaevent_callback(int fd, short event, void* p) { + le_callback* arg = p; + lua_State* L; + int ret; + assert(arg && arg->base && arg->base->loop_L); + L = arg->base->loop_L; + lua_rawgeti(L, LUA_REGISTRYINDEX, arg->callbackRef); + lua_pushinteger(L, event); + lua_call(L, 1, 1); + ret = lua_tointeger(L, -1); + lua_pop(L, 1); + if(ret == -1) { + freeCallbackArgs(arg, L); + } else { + struct event *ev = &arg->ev; + int newEvent = ret; + if(newEvent != event) { // Need to hook up new event... + event_del(ev); + event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, arg); + event_add(ev, NULL); + } + } +} + +static int luaevent_cb_gc(lua_State* L) { + le_callback* arg = luaL_checkudata(L, 1, EVENT_CALLBACK_ARG_MT); + freeCallbackArgs(arg, L); + return 0; +} + +int event_callback_register(lua_State* L) { + luaL_newmetatable(L, EVENT_CALLBACK_ARG_MT); + lua_pushcfunction(L, luaevent_cb_gc); + lua_setfield(L, -2, "__gc"); + lua_newtable(L); + lua_pushcfunction(L, luaevent_cb_gc); + lua_setfield(L, -2, "close"); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); + return 0; +}