diff options
author | Tom Gundersen <teg@jklm.no> | 2014-08-15 23:25:46 +0200 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-08-25 23:18:18 +0200 |
commit | bcede0a9c24f840d0c8cf63dc15756f239e35574 (patch) | |
tree | a43b4c033daee9b846793b13eee08c33d8611608 | |
parent | c45a5a74465a39280b855f9d720b2ab4779a47fa (diff) |
[POC] networkd: port to glib main loopglib-sd-event
Just a test-case for the sd_event hooks, not to be merged (obviously).
This introduces (MIT licensed) glib-event-glue.[ch], which is meant to
end up as an example people could copy. Will probably need to find a home
for it though.
-rw-r--r-- | Makefile.am | 15 | ||||
-rw-r--r-- | src/network/glib-event-glue.c | 74 | ||||
-rw-r--r-- | src/network/glib-event-glue.h | 30 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 28 | ||||
-rw-r--r-- | src/network/networkd.c | 9 | ||||
-rw-r--r-- | src/network/networkd.h | 3 |
6 files changed, 151 insertions, 8 deletions
diff --git a/Makefile.am b/Makefile.am index cbf98bdac..a5a0f7307 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4953,11 +4953,17 @@ systemd_networkd_LDADD = \ libsystemd-networkd-core.la \ libsystemd-capability.la +systemd_networkd_CFLAGS = \ + $(GLIB_CFLAGS) \ + -fPIC + noinst_LTLIBRARIES += \ libsystemd-networkd-core.la libsystemd_networkd_core_la_CFLAGS = \ - $(AM_CFLAGS) + $(AM_CFLAGS) \ + $(GLIB_CFLAGS) \ + -fPIC libsystemd_networkd_core_la_SOURCES = \ src/libsystemd-network/network-internal.h \ @@ -4990,7 +4996,9 @@ libsystemd_networkd_core_la_SOURCES = \ src/network/networkd-address.c \ src/network/networkd-route.c \ src/network/networkd-manager.c \ - src/network/networkd-address-pool.c + src/network/networkd-address-pool.c \ + src/network/glib-event-glue.h \ + src/network/glib-event-glue.c nodist_libsystemd_networkd_core_la_SOURCES = \ src/network/networkd-network-gperf.c \ @@ -5001,7 +5009,8 @@ libsystemd_networkd_core_la_LIBADD = \ libsystemd-internal.la \ libsystemd-network.la \ libsystemd-label.la \ - libsystemd-shared.la + libsystemd-shared.la \ + $(GLIB_LIBS) rootlibexec_PROGRAMS += \ systemd-networkd-wait-online diff --git a/src/network/glib-event-glue.c b/src/network/glib-event-glue.c new file mode 100644 index 000000000..95aaea1e6 --- /dev/null +++ b/src/network/glib-event-glue.c @@ -0,0 +1,74 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + Copyright 2014 Tom Gundersen + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> + +#include "glib-event-glue.h" + +typedef struct SDEventSource { + GSource source; + GPollFD pollfd; + sd_event *event; +} SDEventSource; + +static gboolean event_prepare(GSource *source, gint *timeout_) { + return sd_event_prepare(((SDEventSource *)source)->event) > 0; +} + +static gboolean event_check(GSource *source) { + return sd_event_wait(((SDEventSource *)source)->event, 0) > 0; +} + +static gboolean event_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { + return sd_event_dispatch(((SDEventSource *)source)->event) > 0; +} + +static void event_finalize(GSource *source) { + sd_event_unref(((SDEventSource *)source)->event); +} + +static GSourceFuncs event_funcs = { + .prepare = event_prepare, + .check = event_check, + .dispatch = event_dispatch, + .finalize = event_finalize, +}; + +GSource *g_sd_event_create_source(sd_event *event) { + SDEventSource *source; + + source = (SDEventSource *)g_source_new(&event_funcs, sizeof(SDEventSource)); + + source->event = sd_event_ref(event); + source->pollfd.fd = sd_event_get_fd(event); + source->pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR; + + g_source_add_poll((GSource *)source, &source->pollfd); + + return (GSource *)source; +} diff --git a/src/network/glib-event-glue.h b/src/network/glib-event-glue.h new file mode 100644 index 000000000..f3a593283 --- /dev/null +++ b/src/network/glib-event-glue.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + Copyright 2014 Tom Gundersen + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#include <glib.h> +#include <sd-event.h> + +GSource *g_sd_event_create_source(sd_event *event); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index f2fe5d544..0b722e9cd 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -34,6 +34,8 @@ #include "mkdir.h" #include "virt.h" +#include "glib-event-glue.h" + #include "sd-rtnl.h" const char* const network_dirs[] = { @@ -72,6 +74,16 @@ static int setup_default_address_pool(Manager *m) { return 0; } +static int event_quit(sd_event_source *source, void *userdata) { + GMainLoop *loop = userdata; + + assert(loop); + + g_main_loop_quit(loop); + + return 1; +} + int manager_new(Manager **ret) { _cleanup_manager_free_ Manager *m = NULL; int r; @@ -88,6 +100,20 @@ int manager_new(Manager **ret) { if (r < 0) return r; + m->glue_source = g_sd_event_create_source(m->event); + if (!m->glue_source) + return -ENOMEM; + + m->loop = g_main_loop_new(NULL, true); + if (!m->loop) + return -ENOMEM; + + g_source_attach(m->glue_source, g_main_loop_get_context(m->loop)); + + r = sd_event_add_exit(m->event, NULL, event_quit, m->loop); + if (r < 0) + return r; + sd_event_set_watchdog(m->event, true); sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL); @@ -149,6 +175,8 @@ void manager_free(Manager *m) { sd_event_source_unref(m->sigterm_event_source); sd_event_source_unref(m->sigint_event_source); sd_event_unref(m->event); + g_source_unref(m->glue_source); + g_main_loop_unref(m->loop); while ((link = hashmap_first(m->links))) link_unref(link); diff --git a/src/network/networkd.c b/src/network/networkd.c index fdb80368d..5a61f3614 100644 --- a/src/network/networkd.c +++ b/src/network/networkd.c @@ -19,6 +19,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <glib.h> + #include "capability.h" #include "sd-event.h" #include "sd-daemon.h" @@ -117,11 +119,8 @@ int main(int argc, char *argv[]) { "READY=1\n" "STATUS=Processing requests..."); - r = sd_event_loop(m->event); - if (r < 0) { - log_error("Event loop failed: %s", strerror(-r)); - goto out; - } + g_main_loop_run(m->loop); + r = 0; out: sd_notify(false, diff --git a/src/network/networkd.h b/src/network/networkd.h index ab5df1aa3..598c4b210 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -22,6 +22,7 @@ #pragma once #include <arpa/inet.h> +#include <glib.h> #include "sd-event.h" #include "sd-rtnl.h" @@ -168,6 +169,8 @@ struct AddressPool { struct Manager { sd_rtnl *rtnl; sd_event *event; + GSource *glue_source; + GMainLoop *loop; sd_bus *bus; struct udev *udev; struct udev_monitor *udev_monitor; |