From aca98a4b2c9d0be48be773fbf438a8477698ef14 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Thu, 12 May 2016 16:03:27 -0400 Subject: convert to libevent also remove all code supporting threading stuff --- Makefile | 2 +- README.md | 6 +-- src/daemon.c | 18 +++----- src/loop.c | 109 +++++++++++++++++++++------------------------- src/loop.h | 13 +++--- src/pty-unix.c | 17 +++----- src/window-backend-xlib.c | 2 - src/window-xlib.c | 60 +++++++++++++------------ src/window-xlib.h | 1 - 9 files changed, 105 insertions(+), 123 deletions(-) diff --git a/Makefile b/Makefile index 81900af..a38ceca 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ DOBJ = $(BUILD)runesd.o \ $(BUILD)daemon.o COBJ = $(BUILD)runesc.o \ $(BUILD)util.o -LIBS = cairo cairo-xlib libuv pangocairo +LIBS = cairo cairo-xlib libevent pangocairo OPT ?= -g CFLAGS ?= $(OPT) -Wall -Wextra -Werror LDFLAGS ?= $(OPT) -Wall -Wextra -Werror diff --git a/README.md b/README.md index 3ad8310..11b7444 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,9 @@ looking into new extensions. Building -------- -Runes requires cairo, xlib, and libuv. Once those dependencies are installed, -you should be able to build it just by running `make`. If you're interested in -modifying the parser, you'll also need to install flex. +Runes requires cairo, xlib, and libevent. Once those dependencies are +installed, you should be able to build it just by running `make`. If you're +interested in modifying the parser, you'll also need to install flex. Contributing ------------ diff --git a/src/daemon.c b/src/daemon.c index f286e11..2202b7f 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -14,7 +15,6 @@ static int runes_daemon_open_socket(char *sock_name); static void runes_daemon_close_socket(RunesDaemon *sock); -static void runes_daemon_socket_accept(void *t); static int runes_daemon_handle_request(void *t); RunesDaemon *runes_daemon_new(RunesLoop *loop, RunesWindowBackend *wb) @@ -33,8 +33,8 @@ RunesDaemon *runes_daemon_new(RunesLoop *loop, RunesWindowBackend *wb) void runes_daemon_init_loop(RunesDaemon *daemon, RunesLoop *loop) { - runes_loop_start_work(loop, daemon, runes_daemon_socket_accept, - runes_daemon_handle_request); + runes_loop_start_work( + loop, daemon->sock, daemon, runes_daemon_handle_request); } void runes_socket_delete(RunesDaemon *daemon) @@ -97,23 +97,17 @@ static void runes_daemon_close_socket(RunesDaemon *daemon) unlink(daemon->sock_name); } -static void runes_daemon_socket_accept(void *t) +static int runes_daemon_handle_request(void *t) { RunesDaemon *daemon = (RunesDaemon *)t; struct sockaddr_un client; socklen_t len = sizeof(client); - - daemon->client_sock = accept( - daemon->sock, (struct sockaddr*)(&client), &len); -} - -static int runes_daemon_handle_request(void *t) -{ - RunesDaemon *daemon = (RunesDaemon *)t; ssize_t bytes; uint32_t argc, argv_len; char **argv, *argv_buf; + daemon->client_sock = accept( + daemon->sock, (struct sockaddr*)(&client), &len); if (daemon->client_sock < 0) { runes_die("couldn't accept connection: %s", strerror(errno)); } diff --git a/src/loop.c b/src/loop.c index be3b3ba..a352e1b 100644 --- a/src/loop.c +++ b/src/loop.c @@ -1,117 +1,106 @@ #include +#include #include "runes.h" #include "loop.h" struct runes_loop_data { - uv_work_t req; - RunesLoop *loop; + struct event *event; void *t; - void (*work_cb)(void*); - int (*after_work_cb)(void*); + int (*cb)(void*); }; struct runes_loop_timer_data { + struct event *event; + struct timeval *timeout; void *t; void (*cb)(void*); }; -static void runes_loop_do_work(uv_work_t *req); -static void runes_loop_do_after_work(uv_work_t *req, int status); -static void runes_loop_timer_cb(uv_timer_t *handle); -static void runes_loop_free_handle(uv_handle_t *handle); +static void runes_loop_work_cb(evutil_socket_t fd, short what, void *arg); +static void runes_loop_timer_cb(evutil_socket_t fd, short what, void *arg); RunesLoop *runes_loop_new() { RunesLoop *loop; loop = calloc(1, sizeof(RunesLoop)); - loop->loop = uv_default_loop(); + loop->base = event_base_new(); return loop; } void runes_loop_run(RunesLoop *loop) { - uv_run(loop->loop, UV_RUN_DEFAULT); + event_base_dispatch(loop->base); } -void runes_loop_start_work(RunesLoop *loop, void *t, - void (*work_cb)(void*), - int (*after_work_cb)(void*)) +void runes_loop_start_work( + RunesLoop *loop, int fd, void *t, int (*cb)(void*)) { struct runes_loop_data *data; data = malloc(sizeof(struct runes_loop_data)); - data->req.data = data; - data->loop = loop; + data->event = event_new(loop->base, fd, EV_READ, runes_loop_work_cb, data); data->t = t; - data->work_cb = work_cb; - data->after_work_cb = after_work_cb; + data->cb = cb; - uv_queue_work(loop->loop, (void*)data, runes_loop_do_work, - runes_loop_do_after_work); + event_add(data->event, NULL); } -void runes_loop_timer_set(RunesLoop *loop, int timeout, int repeat, - void *t, void (*cb)(void*)) +void runes_loop_timer_set( + RunesLoop *loop, int timeout, void *t, void (*cb)(void*)) { - uv_timer_t *timer_req; - struct runes_loop_timer_data *timer_data; - - timer_req = malloc(sizeof(uv_timer_t)); - uv_timer_init(loop->loop, timer_req); - timer_data = malloc(sizeof(struct runes_loop_timer_data)); - timer_data->t = t; - timer_data->cb = cb; - timer_req->data = (void *)timer_data; - uv_timer_start(timer_req, runes_loop_timer_cb, timeout, repeat); -} + struct runes_loop_timer_data *data; -void runes_loop_delete(RunesLoop *loop) -{ - uv_loop_close(loop->loop); + data = malloc(sizeof(struct runes_loop_timer_data)); + data->event = event_new(loop->base, -1, 0, runes_loop_timer_cb, data); + data->t = t; + data->cb = cb; + data->timeout = malloc(sizeof(struct timeval)); + data->timeout->tv_sec = 0; + while (timeout >= 1000) { + data->timeout->tv_sec += 1; + timeout -= 1000; + } + data->timeout->tv_usec = timeout * 1000; - free(loop); + event_add(data->event, data->timeout); } -static void runes_loop_do_work(uv_work_t *req) +void runes_loop_delete(RunesLoop *loop) { - struct runes_loop_data *data = req->data; - void *t = data->t; + event_base_free(loop->base); - data->work_cb(t); + free(loop); } -static void runes_loop_do_after_work(uv_work_t *req, int status) +static void runes_loop_work_cb(evutil_socket_t fd, short what, void *arg) { - struct runes_loop_data *data = req->data; - RunesLoop *loop = data->loop; - void *t = data->t; - int should_loop = 0; + struct runes_loop_data *data = arg; - UNUSED(status); + UNUSED(fd); + UNUSED(what); - should_loop = data->after_work_cb(t); - if (should_loop) { - uv_queue_work(loop->loop, req, runes_loop_do_work, - runes_loop_do_after_work); + if (data->cb(data->t)) { + event_add(data->event, NULL); } else { - free(req); + event_free(data->event); + free(data); } } -static void runes_loop_timer_cb(uv_timer_t *handle) +static void runes_loop_timer_cb(evutil_socket_t fd, short what, void *arg) { - struct runes_loop_timer_data *data = handle->data; + struct runes_loop_timer_data *data = arg; + + UNUSED(fd); + UNUSED(what); + data->cb(data->t); - uv_close( - (uv_handle_t *)handle, runes_loop_free_handle); -} -static void runes_loop_free_handle(uv_handle_t *handle) -{ - free(handle->data); - free(handle); + event_free(data->event); + free(data->timeout); + free(data); } diff --git a/src/loop.h b/src/loop.h index 1f8a02f..ccbfdd3 100644 --- a/src/loop.h +++ b/src/loop.h @@ -1,19 +1,18 @@ #ifndef _RUNES_LOOP_H #define _RUNES_LOOP_H -#include +#include struct runes_loop { - uv_loop_t *loop; + struct event_base *base; }; RunesLoop *runes_loop_new(void); void runes_loop_run(RunesLoop *loop); -void runes_loop_start_work(RunesLoop *loop, void *t, - void (*work_cb)(void*), - int (*after_work_cb)(void*)); -void runes_loop_timer_set(RunesLoop *loop, int timeout, int repeat, - void *t, void (*cb)(void*)); +void runes_loop_start_work( + RunesLoop *loop, int fd, void *t, int (*cb)(void*)); +void runes_loop_timer_set( + RunesLoop *loop, int timeout, void *t, void (*cb)(void*)); void runes_loop_delete(RunesLoop *loop); #endif diff --git a/src/pty-unix.c b/src/pty-unix.c index fe7e0c8..ba4ea34 100644 --- a/src/pty-unix.c +++ b/src/pty-unix.c @@ -1,10 +1,12 @@ #define _XOPEN_SOURCE 600 #include #include +#include #include #include #include #include +#include #include #include @@ -16,8 +18,7 @@ #include "term.h" #include "window-xlib.h" -static void runes_pty_read(void *t); -static int runes_pty_got_data(void *t); +static int runes_pty_input_cb(void *t); RunesPty *runes_pty_new() { @@ -103,9 +104,10 @@ void runes_pty_spawn_subprocess(RunesTerm *t) void runes_pty_init_loop(RunesTerm *t, RunesLoop *loop) { + RunesPty *pty = t->pty; + runes_term_refcnt_inc(t); - runes_loop_start_work( - loop, t, runes_pty_read, runes_pty_got_data); + runes_loop_start_work(loop, pty->master, t, runes_pty_input_cb); } void runes_pty_set_window_size( @@ -139,7 +141,7 @@ void runes_pty_delete(RunesPty *pty) free(pty); } -static void runes_pty_read(void *t) +static int runes_pty_input_cb(void *t) { RunesPty *pty = ((RunesTerm *)t)->pty; @@ -147,11 +149,6 @@ static void runes_pty_read(void *t) pty->readlen = read( pty->master, pty->readbuf + pty->remaininglen, RUNES_READ_BUFFER_LENGTH - pty->remaininglen); -} - -static int runes_pty_got_data(void *t) -{ - RunesPty *pty = ((RunesTerm *)t)->pty; if (pty->readlen > 0) { int to_process = pty->readlen + pty->remaininglen; diff --git a/src/window-backend-xlib.c b/src/window-backend-xlib.c index aeb9bf1..8d5f144 100644 --- a/src/window-backend-xlib.c +++ b/src/window-backend-xlib.c @@ -29,8 +29,6 @@ RunesWindowBackend *runes_window_backend_new() { RunesWindowBackend *wb; - XInitThreads(); - setlocale(LC_ALL, ""); XSetLocaleModifiers(""); diff --git a/src/window-xlib.c b/src/window-xlib.c index 8bc844d..eba148d 100644 --- a/src/window-xlib.c +++ b/src/window-xlib.c @@ -74,10 +74,10 @@ static struct function_key application_cursor_keys[] = { }; #undef RUNES_KEY -static void runes_window_get_next_event(void *t); +static int runes_window_event_cb(void *t); +static int runes_window_handle_event(RunesTerm *t, XEvent *e); static Bool runes_window_wants_event( Display *dpy, XEvent *event, XPointer arg); -static int runes_window_process_event(void *t); static Bool runes_window_find_flush_events( Display *dpy, XEvent *e, XPointer arg); static void runes_window_resize_window( @@ -257,7 +257,7 @@ void runes_window_init_loop(RunesTerm *t, RunesLoop *loop) runes_term_refcnt_inc(t); runes_loop_start_work( - loop, t, runes_window_get_next_event, runes_window_process_event); + loop, XConnectionNumber(w->wb->dpy), t, runes_window_event_cb); } void runes_window_request_flush(RunesTerm *t) @@ -271,9 +271,7 @@ void runes_window_request_flush(RunesTerm *t) e.xclient.data.l[0] = w->wb->atoms[RUNES_ATOM_RUNES_FLUSH]; XSendEvent(w->wb->dpy, w->w, False, NoEventMask, &e); - XLockDisplay(w->wb->dpy); XFlush(w->wb->dpy); - XUnlockDisplay(w->wb->dpy); } void runes_window_request_close(RunesTerm *t) @@ -289,9 +287,7 @@ void runes_window_request_close(RunesTerm *t) e.xclient.data.l[1] = CurrentTime; XSendEvent(w->wb->dpy, w->w, False, NoEventMask, &e); - XLockDisplay(w->wb->dpy); XFlush(w->wb->dpy); - XUnlockDisplay(w->wb->dpy); } unsigned long runes_window_get_window_id(RunesTerm *t) @@ -353,27 +349,30 @@ void runes_window_delete(RunesWindow *w) free(w); } -static void runes_window_get_next_event(void *t) +static int runes_window_event_cb(void *t) { RunesWindow *w = ((RunesTerm *)t)->w; + XEvent e; + int should_close = 0; - XIfEvent(w->wb->dpy, &w->event, runes_window_wants_event, t); -} - -static Bool runes_window_wants_event(Display *dpy, XEvent *event, XPointer arg) -{ - RunesWindow *w = ((RunesTerm *)arg)->w; - Window event_window = ((XAnyEvent*)event)->window; + while (XCheckIfEvent(w->wb->dpy, &e, runes_window_wants_event, t)) { + should_close = runes_window_handle_event(((RunesTerm *)t), &e); + if (should_close) { + break; + } + } - UNUSED(dpy); + if (should_close) { + runes_pty_request_close(t); + runes_term_refcnt_dec(t); + } - return event_window == w->w || event_window == w->border_w; + return !should_close; } -static int runes_window_process_event(void *t) +static int runes_window_handle_event(RunesTerm *t, XEvent *e) { RunesWindow *w = ((RunesTerm *)t)->w; - XEvent *e = &w->event; int should_close = 0; if (!XFilterEvent(e, None)) { @@ -441,12 +440,17 @@ static int runes_window_process_event(void *t) } } - if (should_close) { - runes_pty_request_close(t); - runes_term_refcnt_dec(t); - } + return should_close; +} - return !should_close; +static Bool runes_window_wants_event(Display *dpy, XEvent *event, XPointer arg) +{ + RunesWindow *w = ((RunesTerm *)arg)->w; + Window event_window = ((XAnyEvent*)event)->window; + + UNUSED(dpy); + + return event_window == w->w || event_window == w->border_w; } static Bool runes_window_find_flush_events( @@ -567,7 +571,9 @@ static int runes_window_check_recent(RunesTerm *t) } if (now.tv_sec < w->last_redraw.tv_sec || (now.tv_sec == w->last_redraw.tv_sec && now.tv_nsec < w->last_redraw.tv_nsec)) { runes_term_refcnt_inc(t); - runes_loop_timer_set(t->loop, rate, 0, t, runes_window_delay_cb); + runes_warn("setting a timer for %dms", t->config->redraw_rate); + runes_loop_timer_set( + t->loop, t->config->redraw_rate, t, runes_window_delay_cb); w->delaying = 1; return 1; } @@ -581,6 +587,7 @@ static void runes_window_delay_cb(void *t) { RunesWindow *w = ((RunesTerm *)t)->w; + runes_warn("done delaying"); w->delaying = 0; runes_window_request_flush(t); runes_term_refcnt_dec((RunesTerm*)t); @@ -623,8 +630,7 @@ static void runes_window_visual_bell(RunesTerm *t) XFlush(w->wb->dpy); runes_term_refcnt_inc(t); - runes_loop_timer_set( - t->loop, 20, 0, t, runes_window_reset_visual_bell); + runes_loop_timer_set(t->loop, 20, t, runes_window_reset_visual_bell); } } diff --git a/src/window-xlib.h b/src/window-xlib.h index 9b3ad63..914be91 100644 --- a/src/window-xlib.h +++ b/src/window-xlib.h @@ -10,7 +10,6 @@ struct runes_window { Window w; Window border_w; XIC ic; - XEvent event; char *selection_contents; size_t selection_len; struct timespec last_redraw; -- cgit v1.2.3-54-g00ecf