From ea3011941063f2b4f7721fa520a0b9a4069b436f Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Wed, 21 Nov 2012 21:01:12 +0100 Subject: [PATCH] Use glib instead of libev This commit ports awesome from libev to the glib main loop. This means that awesome has fewer dependencies, because we were already depending on glib before and now no longer need glib. However, the main reason for this change is that, thanks to lgi, we have glib bindings for lua. This means that lua code can add all kinds of event sources to the main loop (timeouts, fd watchers, SIGCHLD watchers, ....). Yay Signed-off-by: Uli Schlachter --- awesome.c | 97 ++++++++++++++++++++++------------------------------- awesomeConfig.cmake | 4 --- dbus.c | 58 ++++++++++++++++---------------- globalconf.h | 6 ++-- luaa.c | 4 +-- luaa.h | 2 -- objects/timer.c | 34 +++++++++---------- spawn.c | 32 +++++++----------- 8 files changed, 100 insertions(+), 137 deletions(-) diff --git a/awesome.c b/awesome.c index 1d8cea9d..e629ce1d 100644 --- a/awesome.c +++ b/awesome.c @@ -35,6 +35,8 @@ #include +#include + #include "awesome.h" #include "spawn.h" #include "objects/client.h" @@ -76,8 +78,6 @@ awesome_atexit(bool restart) /* Disconnect *after* closing lua */ xcb_disconnect(globalconf.connection); - - ev_default_destroy(); } /** Scan X to find windows to manage. @@ -156,13 +156,7 @@ scan(xcb_query_tree_cookie_t tree_c) } static void -a_refresh_cb(EV_P_ ev_prepare *w, int revents) -{ - awesome_refresh(); -} - -static void -a_xcb_check_cb(EV_P_ ev_check *w, int revents) +a_xcb_check(void) { xcb_generic_event_t *mouse = NULL, *event; @@ -200,13 +194,25 @@ a_xcb_check_cb(EV_P_ ev_check *w, int revents) } } -static void -a_xcb_io_cb(EV_P_ ev_io *w, int revents) +static gboolean +a_xcb_io_cb(GIOChannel *source, GIOCondition cond, gpointer data) { - /* a_xcb_check_cb() already handled all events */ + /* a_xcb_check() already handled all events */ if(xcb_connection_has_error(globalconf.connection)) fatal("X server connection broke"); + + return TRUE; +} + +static gint +a_glib_poll(GPollFD *ufds, guint nfsd, gint timeout) +{ + guint res; + awesome_refresh(); + res = g_poll(ufds, nfsd, timeout); + a_xcb_check(); + return res; } static void @@ -218,13 +224,13 @@ signal_fatal(int signum) } /** Function to exit on some signals. - * \param w the signal received, unused - * \param revents currently unused + * \param data currently unused */ -static void -exit_on_signal(EV_P_ ev_signal *w, int revents) +static gboolean +exit_on_signal(gpointer data) { - ev_unloop(EV_A_ 1); + g_main_loop_quit(globalconf.loop); + return TRUE; } void @@ -235,13 +241,13 @@ awesome_restart(void) } /** Function to restart awesome on some signals. - * \param w the signal received, unused - * \param revents Currently unused + * \param data currently unused */ -static void -restart_on_signal(EV_P_ ev_signal *w, int revents) +static gboolean +restart_on_signal(gpointer data) { awesome_restart(); + return TRUE; } /** Print help and exit(2) with given exit_code. @@ -285,14 +291,6 @@ main(int argc, char **argv) { NULL, 0, NULL, 0 } }; - /* event loop watchers */ - ev_io xio = { .fd = -1 }; - ev_check xcheck; - ev_prepare a_refresh; - ev_signal sigint; - ev_signal sigterm; - ev_signal sighup; - /* clear the globalconf structure */ p_clear(&globalconf, 1); globalconf.keygrabber = LUA_REFNIL; @@ -354,18 +352,10 @@ main(int argc, char **argv) break; } - globalconf.loop = ev_default_loop(EVFLAG_NOSIGFD); - /* register function for signals */ - ev_signal_init(&sigint, exit_on_signal, SIGINT); - ev_signal_init(&sigterm, exit_on_signal, SIGTERM); - ev_signal_init(&sighup, restart_on_signal, SIGHUP); - ev_signal_start(globalconf.loop, &sigint); - ev_signal_start(globalconf.loop, &sigterm); - ev_signal_start(globalconf.loop, &sighup); - ev_unref(globalconf.loop); - ev_unref(globalconf.loop); - ev_unref(globalconf.loop); + g_unix_signal_add(SIGINT, exit_on_signal, NULL); + g_unix_signal_add(SIGTERM, exit_on_signal, NULL); + g_unix_signal_add(SIGHUP, restart_on_signal, NULL); struct sigaction sa = { .sa_handler = signal_fatal, .sa_flags = 0 }; sigemptyset(&sa.sa_mask); @@ -408,19 +398,17 @@ main(int argc, char **argv) xcb_prefetch_extension_data(globalconf.connection, &xcb_xinerama_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_shape_id); + /* Setup the main context */ + g_main_context_set_poll_func(g_main_context_default(), &a_glib_poll); + /* initialize dbus */ a_dbus_init(); /* Get the file descriptor corresponding to the X connection */ xfd = xcb_get_file_descriptor(globalconf.connection); - ev_io_init(&xio, &a_xcb_io_cb, xfd, EV_READ); - ev_io_start(globalconf.loop, &xio); - ev_check_init(&xcheck, &a_xcb_check_cb); - ev_check_start(globalconf.loop, &xcheck); - ev_unref(globalconf.loop); - ev_prepare_init(&a_refresh, &a_refresh_cb); - ev_prepare_start(globalconf.loop, &a_refresh); - ev_unref(globalconf.loop); + GIOChannel *channel = g_io_channel_unix_new(xfd); + g_io_add_watch(channel, G_IO_IN, a_xcb_io_cb, NULL); + g_io_channel_unref(channel); /* Grab server */ xcb_grab_server(globalconf.connection); @@ -531,15 +519,10 @@ main(int argc, char **argv) xcb_flush(globalconf.connection); /* main event loop */ - ev_loop(globalconf.loop, 0); - - /* cleanup event loop */ - ev_ref(globalconf.loop); - ev_check_stop(globalconf.loop, &xcheck); - ev_ref(globalconf.loop); - ev_prepare_stop(globalconf.loop, &a_refresh); - ev_ref(globalconf.loop); - ev_io_stop(globalconf.loop, &xio); + globalconf.loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(globalconf.loop); + g_main_loop_unref(globalconf.loop); + globalconf.loop = NULL; awesome_atexit(false); diff --git a/awesomeConfig.cmake b/awesomeConfig.cmake index a5923373..515e6f9f 100644 --- a/awesomeConfig.cmake +++ b/awesomeConfig.cmake @@ -159,9 +159,6 @@ macro(a_find_library variable library) endif() endmacro() -# Check for libev -a_find_library(LIB_EV ev) - # Check for backtrace_symbols() include(CheckFunctionExists) check_function_exists(backtrace_symbols HAS_EXECINFO) @@ -198,7 +195,6 @@ endif() set(AWESOME_REQUIRED_LDFLAGS ${AWESOME_COMMON_REQUIRED_LDFLAGS} ${AWESOME_REQUIRED_LDFLAGS} - ${LIB_EV} ${LUA_LIBRARIES}) set(AWESOME_REQUIRED_INCLUDE_DIRS diff --git a/dbus.c b/dbus.c index 30e28092..b5432bf1 100644 --- a/dbus.c +++ b/dbus.c @@ -22,10 +22,10 @@ #include "config.h" #include "dbus.h" +#include #ifdef WITH_DBUS -#include #include #include #include @@ -35,8 +35,8 @@ static DBusConnection *dbus_connection_session = NULL; static DBusConnection *dbus_connection_system = NULL; -ev_io dbusio_ses = { .fd = -1 }; -ev_io dbusio_sys = { .fd = -1 }; +static GSource *session_source = NULL; +static GSource *system_source = NULL; static signal_array_t dbus_signals; @@ -45,17 +45,14 @@ static signal_array_t dbus_signals; * \param dbusio The D-Bus event watcher */ static void -a_dbus_cleanup_bus(DBusConnection *dbus_connection, ev_io *dbusio) +a_dbus_cleanup_bus(DBusConnection *dbus_connection, GSource **source) { if(!dbus_connection) return; - if(dbusio->fd >= 0) - { - ev_ref(EV_DEFAULT_UC); - ev_io_stop(EV_DEFAULT_UC_ dbusio); - dbusio->fd = -1; - } + if (*source != NULL) + g_source_destroy(*source); + *source = NULL; /* This is a shared connection owned by libdbus * Do not close it, only unref @@ -462,7 +459,7 @@ a_dbus_process_request(DBusConnection *dbus_connection, DBusMessage *msg) * \param dbusio The D-Bus event watcher */ static void -a_dbus_process_requests_on_bus(DBusConnection *dbus_connection, ev_io *dbusio) +a_dbus_process_requests_on_bus(DBusConnection *dbus_connection, GSource **source) { DBusMessage *msg; int nmsg = 0; @@ -476,7 +473,7 @@ a_dbus_process_requests_on_bus(DBusConnection *dbus_connection, ev_io *dbusio) if(dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected")) { - a_dbus_cleanup_bus(dbus_connection, dbusio); + a_dbus_cleanup_bus(dbus_connection, source); dbus_message_unref(msg); return; } @@ -496,20 +493,22 @@ a_dbus_process_requests_on_bus(DBusConnection *dbus_connection, ev_io *dbusio) * \param w The D-Bus event watcher * \param revents (not used) */ -static void -a_dbus_process_requests_session(EV_P_ ev_io *w, int revents) +static gboolean +a_dbus_process_requests_session(GIOChannel *source, GIOCondition cond, gpointer data) { - a_dbus_process_requests_on_bus(dbus_connection_session, w); + a_dbus_process_requests_on_bus(dbus_connection_session, &session_source); + return TRUE; } /** Foreword D-Bus process system requests on too the correct function. * \param w The D-Bus event watcher * \param revents (not used) */ -static void -a_dbus_process_requests_system(EV_P_ ev_io *w, int revents) +static gboolean +a_dbus_process_requests_system(GIOChannel *source, GIOCondition cond, gpointer data) { - a_dbus_process_requests_on_bus(dbus_connection_system, w); + a_dbus_process_requests_on_bus(dbus_connection_system, &system_source); + return TRUE; } /** Attempt to request a D-Bus name @@ -588,13 +587,12 @@ a_dbus_release_name(DBusConnection *dbus_connection, const char *name) /** Attempt to create a new connection to D-Bus * \param type The bus type to use when connecting to D-Bus * \param type_name The bus type name eg: "session" or "system" - * \param dbusio The D-Bus event watcher * \param cb Function callback to use when processing requests + * \param source A new GSource that will be used for watching the dbus connection. * \return The requested D-Bus connection on success, NULL on failure. */ static DBusConnection * -a_dbus_connect(DBusBusType type, const char *type_name, - ev_io *dbusio, void *cb) +a_dbus_connect(DBusBusType type, const char *type_name, GIOFunc cb, GSource **source) { int fd; DBusConnection *dbus_connection; @@ -614,16 +612,16 @@ a_dbus_connect(DBusBusType type, const char *type_name, dbus_connection_set_exit_on_disconnect(dbus_connection, false); if(dbus_connection_get_unix_fd(dbus_connection, &fd)) { - fcntl(fd, F_SETFD, FD_CLOEXEC); + GIOChannel *channel = g_io_channel_unix_new(fd); + *source = g_io_create_watch(channel, G_IO_IN); + g_io_channel_unref(channel); - ev_io_init(dbusio, cb, fd, EV_READ); - ev_io_start(EV_DEFAULT_UC_ dbusio); - ev_unref(EV_DEFAULT_UC); + fcntl(fd, F_SETFD, FD_CLOEXEC); } else { warn("cannot get D-Bus connection file descriptor"); - a_dbus_cleanup_bus(dbus_connection, dbusio); + a_dbus_cleanup_bus(dbus_connection, source); } } @@ -636,9 +634,9 @@ void a_dbus_init(void) { dbus_connection_session = a_dbus_connect(DBUS_BUS_SESSION, "session", - &dbusio_ses, a_dbus_process_requests_session); + a_dbus_process_requests_session, &session_source); dbus_connection_system = a_dbus_connect(DBUS_BUS_SYSTEM, "system", - &dbusio_sys, a_dbus_process_requests_system); + a_dbus_process_requests_system, &system_source); } /** Cleanup the D-Bus session and system @@ -646,8 +644,8 @@ a_dbus_init(void) void a_dbus_cleanup(void) { - a_dbus_cleanup_bus(dbus_connection_session, &dbusio_ses); - a_dbus_cleanup_bus(dbus_connection_system, &dbusio_sys); + a_dbus_cleanup_bus(dbus_connection_session, &session_source); + a_dbus_cleanup_bus(dbus_connection_system, &system_source); } /** Retrieve the D-Bus bus by it's name diff --git a/globalconf.h b/globalconf.h index a10f9843..0a756a50 100644 --- a/globalconf.h +++ b/globalconf.h @@ -25,7 +25,7 @@ #define SN_API_NOT_YET_FROZEN #include -#include +#include #include #include @@ -94,8 +94,8 @@ typedef struct lua_State *L; /** All errors messages from loading config files */ buffer_t startup_errors; - /** The event loop */ - struct ev_loop *loop; + /** main loop that awesome is running on */ + GMainLoop *loop; /** The key grabber function */ int keygrabber; /** The mouse pointer grabber function */ diff --git a/luaa.c b/luaa.c index 3fb233b9..e8e56f86 100644 --- a/luaa.c +++ b/luaa.c @@ -21,8 +21,6 @@ #define _GNU_SOURCE -#include - #include #include #include @@ -69,7 +67,7 @@ static char *conffile; static int luaA_quit(lua_State *L) { - ev_unloop(globalconf.loop, 1); + g_main_loop_quit(globalconf.loop); return 0; } diff --git a/luaa.h b/luaa.h index d871964a..7cef3403 100644 --- a/luaa.h +++ b/luaa.h @@ -22,8 +22,6 @@ #ifndef AWESOME_LUA_H #define AWESOME_LUA_H -#include - #include #include diff --git a/objects/timer.c b/objects/timer.c index 25500231..36dc17cf 100644 --- a/objects/timer.c +++ b/objects/timer.c @@ -19,8 +19,6 @@ * */ -#include - #include "globalconf.h" #include "luaa.h" #include "timer.h" @@ -30,27 +28,26 @@ typedef struct { LUA_OBJECT_HEADER bool started; - struct ev_timer timer; + guint source_id; + double timeout; } atimer_t; static lua_class_t timer_class; LUA_OBJECT_FUNCS(timer_class, atimer_t, timer) -static void -ev_timer_emit_signal(struct ev_loop *loop, struct ev_timer *w, int revents) +static gboolean +timer_emit_signal(gpointer data) { - luaA_object_push(globalconf.L, w->data); + luaA_object_push(globalconf.L, data); luaA_object_emit_signal(globalconf.L, -1, "timeout", 0); lua_pop(globalconf.L, 1); + return TRUE; } static int luaA_timer_new(lua_State *L) { luaA_class_new(L, &timer_class); - atimer_t *timer = luaA_checkudata(L, -1, &timer_class); - timer->timer.data = timer; - ev_set_cb(&timer->timer, ev_timer_emit_signal); return 1; } @@ -58,7 +55,7 @@ static int luaA_timer_set_timeout(lua_State *L, atimer_t *timer) { double timeout = luaL_checknumber(L, -1); - ev_timer_set(&timer->timer, timeout, timeout); + timer->timeout = timeout; luaA_object_emit_signal(L, -3, "property::timeout", 0); return 0; } @@ -66,7 +63,7 @@ luaA_timer_set_timeout(lua_State *L, atimer_t *timer) static int luaA_timer_get_timeout(lua_State *L, atimer_t *timer) { - lua_pushnumber(L, timer->timer.repeat); + lua_pushnumber(L, timer->timeout); return 1; } @@ -79,8 +76,8 @@ luaA_timer_start(lua_State *L) else { luaA_object_ref(L, 1); - ev_timer_start(globalconf.loop, &timer->timer); timer->started = true; + timer->source_id = g_timeout_add(timer->timeout * 1000, timer_emit_signal, timer); } return 0; } @@ -91,7 +88,7 @@ luaA_timer_stop(lua_State *L) atimer_t *timer = luaA_checkudata(L, 1, &timer_class); if(timer->started) { - ev_timer_stop(globalconf.loop, &timer->timer); + g_source_remove(timer->source_id); luaA_object_unref(L, timer); timer->started = false; } @@ -105,13 +102,12 @@ luaA_timer_again(lua_State *L) { atimer_t *timer = luaA_checkudata(L, 1, &timer_class); - ev_timer_again(globalconf.loop, &timer->timer); - - if(!timer->started) - { + if (timer->started) + g_source_remove(timer->source_id); + else luaA_object_ref(L, 1); - timer->started = true; - } + timer->started = true; + timer->source_id = g_timeout_add(timer->timeout * 1000, timer_emit_signal, timer); return 0; } diff --git a/spawn.c b/spawn.c index f1edaa91..5790d79f 100644 --- a/spawn.c +++ b/spawn.c @@ -64,10 +64,10 @@ spawn_sequence_remove(SnStartupSequence *s) return false; } -static void -spawn_monitor_timeout(struct ev_loop *loop, ev_timer *w, int revents) +static gboolean +spawn_monitor_timeout(gpointer sequence) { - if(spawn_sequence_remove(w->data)) + if(spawn_sequence_remove(sequence)) { signal_t *sig = signal_array_getbyid(&global_signals, a_strhash((const unsigned char *) "spawn::timeout")); @@ -75,7 +75,7 @@ spawn_monitor_timeout(struct ev_loop *loop, ev_timer *w, int revents) { /* send a timeout signal */ lua_createtable(globalconf.L, 0, 2); - lua_pushstring(globalconf.L, sn_startup_sequence_get_id(w->data)); + lua_pushstring(globalconf.L, sn_startup_sequence_get_id(sequence)); lua_setfield(globalconf.L, -2, "id"); foreach(func, sig->sigfuncs) { @@ -88,8 +88,8 @@ spawn_monitor_timeout(struct ev_loop *loop, ev_timer *w, int revents) else warn("spawn::timeout signal is missing"); } - sn_startup_sequence_unref(w->data); - p_delete(&w); + sn_startup_sequence_unref(sequence); + return FALSE; } static void @@ -114,12 +114,9 @@ spawn_monitor_event(SnMonitorEvent *event, void *data) /* Add a timeout function so we do not wait for this event to complete * for ever */ - struct ev_timer *ev_timeout = p_new(struct ev_timer, 1); - ev_timer_init(ev_timeout, spawn_monitor_timeout, AWESOME_SPAWN_TIMEOUT, 0.); + g_timeout_add_seconds(AWESOME_SPAWN_TIMEOUT, spawn_monitor_timeout, sequence); /* ref the sequence for the callback event */ sn_startup_sequence_ref(sequence); - ev_timeout->data = sequence; - ev_timer_start(globalconf.loop, ev_timeout); break; case SN_MONITOR_EVENT_CHANGED: event_type_str = "spawn::change"; @@ -252,12 +249,12 @@ spawn_init(void) signal_add(&global_signals, "spawn::timeout"); } -static void -spawn_launchee_timeout(struct ev_loop *loop, ev_timer *w, int revents) +static gboolean +spawn_launchee_timeout(gpointer context) { - sn_launcher_context_complete(w->data); - sn_launcher_context_unref(w->data); - p_delete(&w); + sn_launcher_context_complete(context); + sn_launcher_context_unref(context); + return FALSE; } static void @@ -335,10 +332,7 @@ luaA_spawn(lua_State *L) /* app will have AWESOME_SPAWN_TIMEOUT seconds to complete, * or the timeout function will terminate the launch sequence anyway */ - struct ev_timer *ev_timeout = p_new(struct ev_timer, 1); - ev_timer_init(ev_timeout, spawn_launchee_timeout, AWESOME_SPAWN_TIMEOUT, 0.); - ev_timeout->data = context; - ev_timer_start(globalconf.loop, ev_timeout); + g_timeout_add_seconds(AWESOME_SPAWN_TIMEOUT, spawn_launchee_timeout, context); sn_launcher_context_setup_child_process(context); } -- 2.11.4.GIT