luaevent/src/luaevent.c

changeset 2
01b3a96ae760
parent 1
31c782cfe7fe
child 3
5999243fab1d
--- a/luaevent/src/luaevent.c	Sun Jun 10 16:52:55 2007 +0000
+++ b/luaevent/src/luaevent.c	Mon Jun 11 01:08:59 2007 +0000
@@ -74,6 +74,12 @@
 	return 0;
 }
 
+static int luaevent_cb_getfd(lua_State* L) {
+	le_callback* arg = luaL_checkudata(L, 1, EVENT_CALLBACK_ARG_MT);
+	lua_pushinteger(L, arg->ev.ev_fd);
+	return 1;
+}
+
 int getSocketFd(lua_State* L, int idx) {
 	int fd;
 	luaL_checktype(L, idx, LUA_TUSERDATA);
@@ -90,23 +96,35 @@
 /* Expected to be called at the beginning of the coro that uses it.. 
 Value must be kept until coro is complete....
 */
-/* sock, event, callback */
+/* sock, callback */
 static int luaevent_addevent(lua_State* L) {
-	int fd, event, callbackRef;
+	int fd, callbackRef;
+	int top, ret;
 	le_callback* arg;
 	fd = getSocketFd(L, 1);
-	event = luaL_checkinteger(L, 2);
-	luaL_checktype(L, 3, LUA_TFUNCTION);
-	lua_pushvalue(L, 3);
+	luaL_checktype(L, 2, LUA_TFUNCTION);
+	top = lua_gettop(L);
+	/* Preserve the callback function */
+	lua_pushvalue(L, 2);
 	callbackRef = luaL_ref(L, LUA_REGISTRYINDEX);
+	
+	/* Call the callback with all arguments after it to get the loop primed.. */
+	lua_call(L, top - 2, 1);
+	ret = lua_tointeger(L, -1);
+	lua_pop(L, 1);
+	if(ret == -1) { /* Done, no need to setup event */
+		luaL_unref(L, LUA_REGISTRYINDEX, callbackRef);
+		return 0;
+	}
 	arg = lua_newuserdata(L, sizeof(*arg));
 	luaL_getmetatable(L, EVENT_CALLBACK_ARG_MT);
 	lua_setmetatable(L, -2);
 	
 	arg->L = L;
 	arg->callbackRef = callbackRef;
+	
 	/* Setup event... */
-	event_set(&arg->ev, fd, event | EV_PERSIST, luaevent_callback, arg);
+	event_set(&arg->ev, fd, ret | EV_PERSIST, luaevent_callback, arg);
 	event_base_set(getEventBase(L), &arg->ev);
 	event_add(&arg->ev, NULL);
 	return 1;
@@ -157,6 +175,8 @@
 	luaL_newmetatable(L, EVENT_CALLBACK_ARG_MT);
 	lua_pushcfunction(L, luaevent_cb_gc);
 	lua_setfield(L, -2, "__gc");
+	lua_pushcfunction(L, luaevent_cb_getfd);
+	lua_setfield(L, -2, "getfd");
 	lua_pop(L, 1);
 
 	setEventBase(L, event_init());

mercurial