コード例 #1
0
ファイル: event_callback.c プロジェクト: ld-test/luaevent
/* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */
void luaevent_callback(int fd, short event, void* p) {
	le_callback* cb = p;
	lua_State* L;
	int ret;
	struct timeval new_tv = { 0, 0 };
	assert(cb);
	if(!cb->base)
		return; /* Event has already been collected + destroyed */
	assert(cb->base->loop_L);
	L = cb->base->loop_L;
	lua_rawgeti(L, LUA_REGISTRYINDEX, cb->callbackRef);
	lua_pushinteger(L, event);
	if(lua_pcall(L, 1, 2, 0))
	{
		cb->base->errorMessage = luaL_ref(L, LUA_REGISTRYINDEX);
		event_base_loopbreak(cb->base->base);
		lua_pop(L, 2);
		return;
	}
	if(!cb->base) {
		lua_pop(L, 2);
		return; /* event was destroyed during callback */
	}
	/* If nothing is returned, re-use the old event value */
	ret = luaL_optinteger(L, -2, event);
	/* Clone the old timeout value in case a new one wasn't set */
	memcpy(&new_tv, &cb->timeout, sizeof(new_tv));
	if(lua_isnumber(L, -1)) {
		double newTimeout = lua_tonumber(L, -1);
		if(newTimeout > 0) {
			load_timeval(newTimeout, &new_tv);
		}
	}
	lua_pop(L, 2);
	if(ret == -1) {
		freeCallbackArgs(cb, L);
	} else {
		struct event *ev = &cb->ev;
		int newEvent = ret;
		if( newEvent != event || (cb->timeout.tv_sec != new_tv.tv_sec || cb->timeout.tv_usec != new_tv.tv_usec) ) {
			struct timeval *ptv = &cb->timeout;
			cb->timeout = new_tv;
			if(!cb->timeout.tv_sec && !cb->timeout.tv_usec)
				ptv = NULL;
			event_del(ev);
			event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, cb);
			/* Assume cannot set a new timeout.. */
			event_add(ev, ptv);
		}
	}
}
コード例 #2
0
static int luaevent_cb_gc(lua_State* L) {
	le_callback* arg = luaL_checkudata(L, 1, EVENT_CALLBACK_ARG_MT);
	freeCallbackArgs(arg, L);
	return 0;
}