src/event_callback.c

Wed, 05 Sep 2007 22:48:49 -0400

author
Thomas Harning Jr <harningt@gmail.com>
date
Wed, 05 Sep 2007 22:48:49 -0400
changeset 20
71bc2e49366c
child 21
728aafac9682
permissions
-rw-r--r--

Beginning refactoring of the event_callback outside of the core

#include "event_callback.h"
#include <assert.h>
#include <lauxlib.h>

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;
}

mercurial