コード例 #1
0
ファイル: mainloop.c プロジェクト: esmil/lem-pulseaudio
static struct pa_io_event *
io_new(pa_mainloop_api *a, int fd, pa_io_event_flags_t events,
		pa_io_event_cb_t cb, void *userdata)
{
	struct pa_io_event *ev = lem_xmalloc(sizeof(struct pa_io_event));
	int revents = 0;

	(void)a;
	lem_debug("flags = %d", events);

	if (events & PA_IO_EVENT_INPUT)
		revents |= EV_READ;
	if (events & PA_IO_EVENT_OUTPUT)
		revents |= EV_WRITE;
	if (events & PA_IO_EVENT_HANGUP)
		revents |= EV_READ;

	ev_io_init(&ev->w, io_handler, fd, revents);
	ev->w.data = userdata;
	ev->cb = cb;
	ev->destroy = NULL;

	if (revents)
		ev_io_start(LEM_ &ev->w);
	return ev;
}
コード例 #2
0
ファイル: mainloop.c プロジェクト: esmil/lem-pulseaudio
static struct pa_defer_event *
defer_new(pa_mainloop_api *a, pa_defer_event_cb_t cb, void *userdata)
{
	struct pa_defer_event *ev = lem_xmalloc(sizeof(struct pa_defer_event));

	(void)a;
	lem_debug("new defer %p", ev);

	ev_idle_init(&ev->w, defer_handler);
	ev->w.data = userdata;
	ev->cb = cb;
	ev->destroy = NULL;

	ev_idle_start(LEM_ &ev->w);
	return ev;
}
コード例 #3
0
ファイル: file.c プロジェクト: halfd/lem
static int
file_gc(lua_State *T)
{
	struct file *f = lua_touserdata(T, 1);

	lem_debug("collecting %p, fd = %d", f, f->fd);
	if (f->fd >= 0) {
		struct file_gc *gc = lem_xmalloc(sizeof(struct file_gc));

		gc->fd = f->fd;
		f->fd = -1;
		lem_async_do(&gc->a, file_gc_work, NULL);
	}

	return 0;
}
コード例 #4
0
ファイル: lem.c プロジェクト: halfd/lem
void
lem_queue(lua_State *T, int nargs)
{
	struct lem_runqueue_slot *slot;

	assert(T != NULL);
	lem_debug("enqueueing thread with %d argument%s",
	              nargs, nargs == 1 ? "" : "s");

	if (rq.first == rq.last)
		ev_idle_start(LEM_ &rq.w);

	slot = &rq.queue[rq.last];
	slot->T = T;
	slot->nargs = nargs;

	rq.last++;
	rq.last &= rq.mask;
	if (rq.first == rq.last) {
		unsigned int i;
		unsigned int j;
		struct lem_runqueue_slot *new_queue;

		lem_debug("expanding queue to %u slots", 2*(rq.mask + 1));
		new_queue = lem_xmalloc(2*(rq.mask + 1)
				* sizeof(struct lem_runqueue_slot));

		i = 0;
		j = rq.first;
		do {
			new_queue[i] = rq.queue[j];

			i++;
			j++;
			j &= rq.mask;
		} while (j != rq.first);

		free(rq.queue);
		rq.queue = new_queue;
		rq.first = 0;
		rq.last = i;
		rq.mask = 2*rq.mask + 1;
	}
}
コード例 #5
0
ファイル: mainloop.c プロジェクト: esmil/lem-pulseaudio
static struct pa_time_event *
time_new(pa_mainloop_api *a, const struct timeval *tv,
		pa_time_event_cb_t cb, void *userdata)
{
	struct pa_time_event *ev = lem_xmalloc(sizeof(struct pa_time_event));
	ev_tstamp timeout = timeval_to_stamp(tv);

	(void)a;
	lem_debug("after = %f seconds", timeout - ev_now(LEM));

	ev->w.data = userdata;
	ev->tv.tv_sec = tv->tv_sec;
	ev->tv.tv_usec = tv->tv_usec;
	ev->cb = cb;
	ev->destroy = NULL;

	ev_timer_init(&ev->w, time_handler, timeout - ev_now(LEM), 0);
	ev_timer_start(LEM_ &ev->w);
	return ev;
}
コード例 #6
0
ファイル: stream.c プロジェクト: esmil/lem
static int
stream_sendfile(lua_State *T)
{
	struct stream *s;
	struct file *f;
	off_t size;
	off_t offset;
	struct sfhandle *sf;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	luaL_checktype(T, 2, LUA_TUSERDATA);
	size = (off_t)luaL_checknumber(T, 3);
	offset = (off_t)luaL_optnumber(T, 4, 0);

	s = lua_touserdata(T, 1);
	if (!s->open)
		return io_closed(T);
	if (s->w.data != NULL)
		return io_busy(T);

	f = lua_touserdata(T, 2);
	if (f->fd < 0) {
		lua_pushnil(T);
		lua_pushliteral(T, "file closed");
		return 2;
	}

	s->w.data = T;

	sf = lem_xmalloc(sizeof(struct sfhandle));
	sf->T = T;
	sf->s = s;
	sf->size = size;
	sf->offset = offset;
	sf->fd = f->fd;
	lem_async_do(&sf->a, stream_sendfile_work, stream_sendfile_reap);

	lua_settop(T, 2);
	return lua_yield(T, 2);
}
コード例 #7
0
ファイル: core.c プロジェクト: ra-kalai/lem-sqlite3
static int
db_open(lua_State *T)
{
	const char *filename = luaL_checkstring(T, 1);
#if SQLITE_VERSION_NUMBER >= 3005000
	int flags = luaL_optnumber(T, 2, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
#endif
	struct db *db;

	db = lem_xmalloc(sizeof(struct db));
	db->T = T;
	db->handle = NULL;
	db->refs = 1;
	db->req.open.filename = filename;
#if SQLITE_VERSION_NUMBER >= 3005000
	db->req.open.flags = flags;
#endif
	lem_async_do(&db->a, db_open_work, db_open_reap);

	lua_settop(T, 1);
	lua_pushvalue(T, lua_upvalueindex(1));
	return lua_yield(T, 2);
}
コード例 #8
0
ファイル: dbus.c プロジェクト: dtaht/lem-dbus
static dbus_bool_t
watch_add(DBusWatch *watch, void *data)
{
	struct watch *w;

	lem_debug("watch = %p, fd = %d, flags = %s, enabled = %s",
	          (void *)watch,
		  dbus_watch_get_unix_fd(watch),
	          dbus_watch_get_flags(watch) & DBUS_WATCH_READABLE ? "READ" : "WRITE",
		  dbus_watch_get_enabled(watch) ? "true" : "false");

	w = lem_xmalloc(sizeof(struct watch));
	ev_io_init(&w->ev, watch_handler, dbus_watch_get_unix_fd(watch),
	           flags_to_revents(dbus_watch_get_flags(watch)));
	w->conn = data;
	w->watch = watch;
	dbus_watch_set_data(watch, w, NULL);

	if (dbus_watch_get_enabled(watch))
		ev_io_start(EV_G_ &w->ev);

	return TRUE;
}
コード例 #9
0
ファイル: dbus.c プロジェクト: dtaht/lem-dbus
static dbus_bool_t
timeout_add(DBusTimeout *timeout, void *data)
{
	struct timeout *t;
	ev_tstamp interval = dbus_timeout_get_interval(timeout);

	lem_debug("timeout = %p, interval = %d, enabled = %s",
	          (void *)timeout,
	          dbus_timeout_get_interval(timeout),
	          dbus_timeout_get_enabled(timeout) ? "true" : "false");

	t = lem_xmalloc(sizeof(struct timeout));
	interval = ((ev_tstamp)dbus_timeout_get_interval(timeout))/1000.0;
	ev_timer_init(&t->ev, timeout_handler, interval, interval);
	t->conn = data;
	t->timeout = timeout;

	dbus_timeout_set_data(timeout, t, NULL);

	if (dbus_timeout_get_enabled(timeout))
		ev_timer_start(EV_G_ &t->ev);

	return TRUE;
}
コード例 #10
0
ファイル: core.c プロジェクト: ifzz/lem
static int
signal_os_watch(lua_State *T, int sig)
{
	struct sigwatcher *s;

	if (sigismember(&signal_sigset, sig))
		goto out; /* already watched */

	s = lem_xmalloc(sizeof(struct sigwatcher));

	signal_watcher_init(s, sig);
	ev_set_priority(&s->w, EV_MAXPRI);
	ev_signal_start(LEM_ &s->w);
	ev_unref(LEM); /* watcher shouldn't keep loop alive */

	sigaddset(&signal_sigset, sig);
	pthread_sigmask(SIG_UNBLOCK, &signal_sigset, NULL);

	s->next = signal_watchers;
	signal_watchers = s;
out:
	lua_pushboolean(T, 1);
	return 1;
}
コード例 #11
0
ファイル: lem.c プロジェクト: halfd/lem
int
main(int argc, char *argv[])
{
#if EV_MULTIPLICITY
	lem_loop = ev_default_loop(LEM_LOOPFLAGS);
	if (lem_loop == NULL) {
#else
	if (!ev_default_loop(LEM_LOOPFLAGS)) {
#endif
		lem_log_error("lem: error initializing event loop");
		return EXIT_FAILURE;
	}

	if (setsignal(SIGPIPE, SIG_IGN, 0)
#if !EV_CHILD_ENABLE
	    || setsignal(SIGCHLD, SIG_DFL, SA_NOCLDSTOP | SA_NOCLDWAIT)
#endif
	   )
		goto error;

	/* create main Lua state */
	L = luaL_newstate();
	if (L == NULL) {
		lem_log_error("lem: error initializing Lua state");
		goto error;
	}
	luaL_openlibs(L);

	/* push thread table */
	lua_newtable(L);

	/* initialize runqueue */
	ev_idle_init(&rq.w, runqueue_pop);
	ev_idle_start(LEM_ &rq.w);
	rq.queue = lem_xmalloc(LEM_INITIAL_QUEUESIZE
			* sizeof(struct lem_runqueue_slot));
	rq.first = rq.last = 0;
	rq.mask = LEM_INITIAL_QUEUESIZE - 1;

	/* initialize threadpool */
	if (pool_init()) {
		lem_log_error("lem: error initializing threadpool");
		goto error;
	}

	/* load file */
	if (queue_file(argc, argv, 1))
		goto error;

	/* start the mainloop */
	ev_loop(LEM_ 0);
	lem_debug("event loop exited");

	/* if there is an error message left on L print it */
	if (lua_type(L, -1) == LUA_TSTRING)
		lem_log_error("lem: %s", lua_tostring(L, -1));

	/* shutdown Lua */
	lua_close(L);

	/* free runqueue */
	free(rq.queue);

	/* destroy loop */
#if EV_MULTIPLICITY
	ev_loop_destroy(lem_loop);
#else
	ev_default_destroy();
#endif
	lem_debug("Bye %s", exit_status == EXIT_SUCCESS ? "o/" : ":(");
	return exit_status;

error:
	if (L)
		lua_close(L);
	if (rq.queue)
		free(rq.queue);
#if EV_MULTIPLICITY
	ev_loop_destroy(lem_loop);
#else
	ev_default_destroy();
#endif
	return EXIT_FAILURE;
}