summary refs log tree commit diff
path: root/src/systemd/nm-sd.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2016-03-30 00:56:30 +0200
committerMichael Biebl <biebl@debian.org>2016-03-30 00:56:30 +0200
commitd9c99a29a0d3384c9c3d2adce430f5cb1134ab6a (patch)
treefa41baf72753961e71dd8d5bdbe2b89c9109e4f1 /src/systemd/nm-sd.c
parentc2de0d98ba39e0a1a970d066fd19be786092f376 (diff)
Imported Upstream version 1.1.92 upstream/1.1.92
Diffstat (limited to 'src/systemd/nm-sd.c')
-rw-r--r--src/systemd/nm-sd.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/systemd/nm-sd.c b/src/systemd/nm-sd.c
new file mode 100644
index 00000000..4d596020
--- /dev/null
+++ b/src/systemd/nm-sd.c
@@ -0,0 +1,136 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2014 - 2016 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+
+#include "nm-sd.h"
+
+#include "sd-event.h"
+
+/*****************************************************************************
+ * Integrating sd_event into glib. Taken and adjusted from
+ * https://www.freedesktop.org/software/systemd/man/sd_event_get_fd.html
+ *****************************************************************************/
+
+typedef struct SDEventSource {
+	GSource source;
+	GPollFD pollfd;
+	sd_event *event;
+	guint *default_source_id;
+} 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)
+{
+	SDEventSource *s;
+
+	s = (SDEventSource *) source;
+	sd_event_unref (s->event);
+	if (s->default_source_id)
+		*s->default_source_id = 0;
+}
+
+static SDEventSource *
+event_create_source (sd_event *event, guint *default_source_id)
+{
+	static GSourceFuncs event_funcs = {
+		.prepare = event_prepare,
+		.check = event_check,
+		.dispatch = event_dispatch,
+		.finalize = event_finalize,
+	};
+	SDEventSource *source;
+
+	g_return_val_if_fail (event, NULL);
+
+	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;
+	source->default_source_id = default_source_id;
+
+	g_source_add_poll ((GSource *) source, &source->pollfd);
+
+	return source;
+}
+
+static guint
+event_attach (sd_event *event, GMainContext *context)
+{
+	SDEventSource *source;
+	guint id;
+	int r;
+	sd_event *e = event;
+	guint *p_default_source_id = NULL;
+
+	if (!e) {
+		static guint default_source_id = 0;
+
+		if (default_source_id) {
+			/* The default event cannot be registered multiple times. */
+			g_return_val_if_reached (0);
+		}
+
+		r = sd_event_default (&e);
+		if (r < 0)
+			g_return_val_if_reached (0);
+
+		p_default_source_id = &default_source_id;
+	}
+
+	source = event_create_source (e, p_default_source_id);
+	id = g_source_attach ((GSource *) source, context);
+	g_source_unref ((GSource *) source);
+
+
+	if (!event) {
+		*p_default_source_id = id;
+		sd_event_unref (e);
+	}
+
+	g_return_val_if_fail (id, 0);
+	return id;
+}
+
+guint
+nm_sd_event_attach_default (void)
+{
+	return event_attach (NULL, NULL);
+}
+
+/*****************************************************************************/
+