diff options
Diffstat (limited to 'libnm/nm-dbus-helpers.c')
| -rw-r--r-- | libnm/nm-dbus-helpers.c | 153 |
1 files changed, 12 insertions, 141 deletions
diff --git a/libnm/nm-dbus-helpers.c b/libnm/nm-dbus-helpers.c index e8cf0436..a27b7e86 100644 --- a/libnm/nm-dbus-helpers.c +++ b/libnm/nm-dbus-helpers.c @@ -1,20 +1,6 @@ +// SPDX-License-Identifier: LGPL-2.1+ /* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright 2013 Red Hat, Inc. + * Copyright (C) 2013 Red Hat, Inc. */ #include "nm-default.h" @@ -23,137 +9,22 @@ #include "nm-dbus-interface.h" -static GBusType nm_bus = G_BUS_TYPE_SYSTEM; - GBusType _nm_dbus_bus_type (void) { - static gsize init_value = 0; + static volatile int bus_type = G_BUS_TYPE_NONE; + int v; - if (g_once_init_enter (&init_value)) { + v = g_atomic_int_get (&bus_type); + if (G_UNLIKELY (v == G_BUS_TYPE_NONE)) { + v = G_BUS_TYPE_SYSTEM; if (g_getenv ("LIBNM_USE_SESSION_BUS")) - nm_bus = G_BUS_TYPE_SESSION; - - g_once_init_leave (&init_value, 1); + v = G_BUS_TYPE_SESSION; + if (!g_atomic_int_compare_and_exchange (&bus_type, G_BUS_TYPE_NONE, v)) + v = g_atomic_int_get (&bus_type); + nm_assert (v != G_BUS_TYPE_NONE); } - - return nm_bus; -} - -GDBusConnection * -_nm_dbus_new_connection (GCancellable *cancellable, GError **error) -{ - return g_bus_get_sync (_nm_dbus_bus_type (), cancellable, error); -} - -static void -new_connection_async_got_system (GObject *source, GAsyncResult *result, gpointer user_data) -{ - GSimpleAsyncResult *simple = user_data; - GDBusConnection *connection; - GError *error = NULL; - - connection = g_bus_get_finish (result, &error); - if (connection) - g_simple_async_result_set_op_res_gpointer (simple, connection, g_object_unref); - else - g_simple_async_result_take_error (simple, error); - - g_simple_async_result_complete (simple); - g_object_unref (simple); -} - -void -_nm_dbus_new_connection_async (GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - - simple = g_simple_async_result_new (NULL, callback, user_data, _nm_dbus_new_connection_async); - if (cancellable) - g_simple_async_result_set_check_cancellable (simple, cancellable); - - g_bus_get (_nm_dbus_bus_type (), - cancellable, - new_connection_async_got_system, simple); -} - -GDBusConnection * -_nm_dbus_new_connection_finish (GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); - - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - - return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); -} - -gboolean -_nm_dbus_is_connection_private (GDBusConnection *connection) -{ - return g_dbus_connection_get_unique_name (connection) == NULL; -} - -/* D-Bus has an upper limit on number of Match rules and it's rather easy - * to hit as the proxy likes to add one for each object. Let's remove the Match - * rule the proxy added and ensure a less granular rule is present instead. - * - * Also, don't do this immediately since it has a performance penalty. - * Still better than losing the signals altogether. - * - * Ideally, we should be able to tell glib not to hook its rules: - * https://bugzilla.gnome.org/show_bug.cgi?id=758749 - */ -void -_nm_dbus_proxy_replace_match (GDBusProxy *proxy) -{ - GDBusConnection *connection = g_dbus_proxy_get_connection (proxy); - static unsigned match_counter = 1024; - char *match; - - if (match_counter == 1) { - /* If we hit the low matches watermark, install a - * less granular one. */ - g_dbus_connection_call (connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "AddMatch", - g_variant_new ("(s)", "type='signal',sender='" NM_DBUS_SERVICE "'"), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - NULL, - NULL); - } - - if (match_counter) - match_counter--; - if (match_counter) - return; - - /* Remove what this proxy added. */ - match = g_strdup_printf ("type='signal',sender='" NM_DBUS_SERVICE "'," - "interface='%s',path='%s'", - g_dbus_proxy_get_interface_name (proxy), - g_dbus_proxy_get_object_path (proxy)); - g_dbus_connection_call (connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "RemoveMatch", - g_variant_new ("(s)", match), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - NULL, - NULL); - g_free (match); + return v; } /* Binds the properties on a generated server-side GDBus object to the |