# HG changeset patch # User Thomas Harning Jr # Date 1189049626 14400 # Node ID 897150985f13672d3d101e4e9179d2ca144ea109 # Parent 48a109847dce242a659513d08bb8bceb4803576a Added support for timeouts and timers. diff -r 48a109847dce -r 897150985f13 include/event_callback.h --- a/include/event_callback.h Wed Sep 05 23:05:05 2007 -0400 +++ b/include/event_callback.h Wed Sep 05 23:33:46 2007 -0400 @@ -13,6 +13,7 @@ struct event ev; le_base* base; int callbackRef; + struct timeval timeout; } le_callback; int event_callback_register(lua_State* L); diff -r 48a109847dce -r 897150985f13 include/luaevent.h --- a/include/luaevent.h Wed Sep 05 23:05:05 2007 -0400 +++ b/include/luaevent.h Wed Sep 05 23:33:46 2007 -0400 @@ -14,6 +14,7 @@ } le_base; le_base* event_base_get(lua_State* L, int idx); +void load_timeval(double time, struct timeval *tv); int luaopen_luaevent(lua_State* L); diff -r 48a109847dce -r 897150985f13 src/event_callback.c --- a/src/event_callback.c Wed Sep 05 23:05:05 2007 -0400 +++ b/src/event_callback.c Wed Sep 05 23:33:46 2007 -0400 @@ -18,25 +18,39 @@ /* 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; + le_callback* cb = 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); + double newTimeout = -1; + assert(cb && cb->base && cb->base->loop_L); + L = cb->base->loop_L; + lua_rawgeti(L, LUA_REGISTRYINDEX, cb->callbackRef); lua_pushinteger(L, event); - lua_call(L, 1, 1); - ret = lua_tointeger(L, -1); + lua_call(L, 1, 2); + ret = lua_tointeger(L, -2); + if(lua_isnumber(L, -1)) { + newTimeout = lua_tonumber(L, -1); + if(newTimeout <= 0) { + memset(&cb->timeout, 0, sizeof(arg->timeout)); + } else { + load_timeval(newTimeout, &cb->timeout); + } + } lua_pop(L, 1); if(ret == -1) { - freeCallbackArgs(arg, L); + freeCallbackArgs(cb, L); } else { - struct event *ev = &arg->ev; + struct event *ev = &cb->ev; int newEvent = ret; - if(newEvent != event) { // Need to hook up new event... + /* NOTE: Currently, even if new timeout is the same as the old, a new event is setup regardless... */ + if(newEvent != event || newTimeout != -1) { // Need to hook up new event... + struct timeval *ptv = &cb->timeout; + if(!cb->timeout.sec && !cb->timeout.usec) + ptv = NULL; event_del(ev); - event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, arg); - event_add(ev, NULL); + event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, cb); + /* Assume cannot set a new timeout.. */ + event_add(ev, ptv); } } } @@ -58,6 +72,7 @@ lua_pushvalue(L, callbackIdx); cb->callbackRef = luaL_ref(L, LUA_REGISTRYINDEX); cb->base = base; + memset(&cb->timeout, 0, sizeof(cb->timeout)); return cb; } diff -r 48a109847dce -r 897150985f13 src/luaevent.c --- a/src/luaevent.c Wed Sep 05 23:05:05 2007 -0400 +++ b/src/luaevent.c Wed Sep 05 23:33:46 2007 -0400 @@ -45,16 +45,33 @@ return fd; } -/* sock, event, callback */ +void load_timeval(double time, struct timeval *tv) { + tv->sec = (int)time; + tv->usec = (time * 1000000) % 1000000; +} + +/* sock, event, callback, timeout */ static int luaevent_addevent(lua_State* L) { int fd, event; le_callback* arg = event_callback_push(L, 1, 4); - fd = getSocketFd(L, 2); + struct timeval *tv = &arg->timeout; + if(lua_isnil(L, 2) && lua_isnumber(L, 5)) { + fd = -1; /* Per event_timer_set.... */ + } else { + fd = getSocketFd(L, 2); + } event = luaL_checkinteger(L, 3); + if(lua_isnumber(L, 5)) { + double time = lua_tonumber(L, 5); + load_timeval(time, tv); + } else { + tv = NULL; + } + /* Setup event... */ event_set(&arg->ev, fd, event | EV_PERSIST, luaevent_callback, arg); event_base_set(arg->base->base, &arg->ev); - event_add(&arg->ev, NULL); + event_add(&arg->ev, tv); return 1; } @@ -86,6 +103,7 @@ {"LEAVE", -1}, {"EV_READ", EV_READ}, {"EV_WRITE", EV_WRITE}, + {"EV_TIMEOUT", EV_TIMEOUT}, {NULL, 0} };