aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThomas Harning Jr <harningt@gmail.com>2007-09-05 23:33:46 -0400
committerThomas Harning Jr <harningt@gmail.com>2007-09-05 23:33:46 -0400
commitfb5f78f8c75ce907ae2796d4300c7f8053d20732 (patch)
treeb4ba07932f35e29e431af481165812efab48769b /src
parent3bf12e614c65f22f012b35a19eafad28ad3d4ed5 (diff)
downloadluaevent-prosody-fb5f78f8c75ce907ae2796d4300c7f8053d20732.tar.gz
luaevent-prosody-fb5f78f8c75ce907ae2796d4300c7f8053d20732.zip
Added support for timeouts and timers.
Diffstat (limited to 'src')
-rw-r--r--src/event_callback.c37
-rw-r--r--src/luaevent.c24
2 files changed, 47 insertions, 14 deletions
diff --git a/src/event_callback.c b/src/event_callback.c
index f2cd0bc..4a6c04d 100644
--- a/src/event_callback.c
+++ b/src/event_callback.c
@@ -18,25 +18,39 @@ 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;
+ 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 @@ le_callback* event_callback_push(lua_State* L, int baseIdx, int callbackIdx) {
lua_pushvalue(L, callbackIdx);
cb->callbackRef = luaL_ref(L, LUA_REGISTRYINDEX);
cb->base = base;
+ memset(&cb->timeout, 0, sizeof(cb->timeout));
return cb;
}
diff --git a/src/luaevent.c b/src/luaevent.c
index 4cadbb5..596e4e1 100644
--- a/src/luaevent.c
+++ b/src/luaevent.c
@@ -45,16 +45,33 @@ int getSocketFd(lua_State* L, int idx) {
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 @@ static namedInteger consts[] = {
{"LEAVE", -1},
{"EV_READ", EV_READ},
{"EV_WRITE", EV_WRITE},
+ {"EV_TIMEOUT", EV_TIMEOUT},
{NULL, 0}
};