summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-08-15 23:25:46 +0200
committerTom Gundersen <teg@jklm.no>2014-08-25 23:18:18 +0200
commitbcede0a9c24f840d0c8cf63dc15756f239e35574 (patch)
treea43b4c033daee9b846793b13eee08c33d8611608
parentc45a5a74465a39280b855f9d720b2ab4779a47fa (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.am15
-rw-r--r--src/network/glib-event-glue.c74
-rw-r--r--src/network/glib-event-glue.h30
-rw-r--r--src/network/networkd-manager.c28
-rw-r--r--src/network/networkd.c9
-rw-r--r--src/network/networkd.h3
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;