Added support for timeouts and timers.

Wed, 05 Sep 2007 23:33:46 -0400

author
Thomas Harning Jr <harningt@gmail.com>
date
Wed, 05 Sep 2007 23:33:46 -0400
changeset 23
897150985f13
parent 22
48a109847dce
child 24
cda8e1a2dfa2

Added support for timeouts and timers.

include/event_callback.h file | annotate | diff | comparison | revisions
include/luaevent.h file | annotate | diff | comparison | revisions
src/event_callback.c file | annotate | diff | comparison | revisions
src/luaevent.c file | annotate | diff | comparison | revisions
--- 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);
--- 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);
 
--- 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;
 }
 
--- 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}
 };
 

mercurial