diff options
author | Thomas Haller <thaller@redhat.com> | 2019-06-30 10:33:28 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-07-01 09:05:54 +0200 |
commit | 79878fc9bd9dbe3d5fc9137e075dcaf3af21bd23 (patch) | |
tree | c6fd3b53b42077c41681d79f343682711c9d0054 | |
parent | d6ce3776a75045926c61ee6c9e5ca1e4649d690a (diff) | |
download | NetworkManager-th/various-settings-cleanup-4.tar.gz |
core: create virtual device on settings changes in idle handlerth/various-settings-cleanup-4
The callback from NMSettings about adding/updating a settings comes
from a deep call-stack already. We don't know the context of it, and
we shouldn't just right away create the profile. Instead, schedule an
action to create it in an idle handler.
-rw-r--r-- | src/nm-manager.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/src/nm-manager.c b/src/nm-manager.c index c961ebc045..d2dd2f4d51 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -176,6 +176,9 @@ typedef struct { NMSettings *settings; + CList connection_changed_on_idle_lst; + guint connection_changed_on_idle_id; + RadioState radio_states[RFKILL_TYPE_MAX]; NMVpnManager *vpn_manager; @@ -2064,6 +2067,7 @@ static void connection_changed (NMManager *self, NMSettingsConnection *sett_conn) { + NMManagerPrivate *priv; NMConnection *connection; NMDevice *device; @@ -2071,6 +2075,11 @@ connection_changed (NMManager *self, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)) return; + priv = NM_MANAGER_GET_PRIVATE (self); + + if (!nm_settings_has_connection (priv->settings, sett_conn)) + return; + connection = nm_settings_connection_get_connection (sett_conn); if (!nm_connection_is_virtual (connection)) @@ -2086,12 +2095,46 @@ connection_changed (NMManager *self, retry_connections_for_parent_device (self, device); } +static gboolean +connection_changed_on_idle_cb (gpointer user_data) +{ + NMManager *self = user_data; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMCListElem *elem; + + priv->connection_changed_on_idle_id = 0; + + while ((elem = c_list_first_entry (&priv->connection_changed_on_idle_lst, NMCListElem, lst))) { + gs_unref_object NMSettingsConnection *sett_conn = NULL; + + sett_conn = nm_c_list_elem_free_steal (elem); + connection_changed (self, sett_conn); + } + + return G_SOURCE_REMOVE; +} + +static void +connection_changed_on_idle (NMManager *self, + NMSettingsConnection *sett_conn) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + + if (priv->connection_changed_on_idle_id == 0) + priv->connection_changed_on_idle_id = g_idle_add (connection_changed_on_idle_cb, self); + + if (!nm_c_list_elem_find_first (&priv->connection_changed_on_idle_lst, sett_conn)) { + c_list_link_tail (&priv->connection_changed_on_idle_lst, + &nm_c_list_elem_new_stale (g_object_ref (sett_conn))->lst); + } +} + static void connection_added_cb (NMSettings *settings, NMSettingsConnection *sett_conn, NMManager *self) { - connection_changed (self, sett_conn); + connection_changed_on_idle (self, sett_conn); } static void @@ -2100,7 +2143,7 @@ connection_updated_cb (NMSettings *settings, gboolean by_user, NMManager *self) { - connection_changed (self, sett_conn); + connection_changed_on_idle (self, sett_conn); } /*****************************************************************************/ @@ -7357,6 +7400,7 @@ nm_manager_init (NMManager *self) c_list_init (&priv->active_connections_lst_head); c_list_init (&priv->async_op_lst_head); c_list_init (&priv->delete_volatile_connection_lst_head); + c_list_init (&priv->connection_changed_on_idle_lst); priv->platform = g_object_ref (NM_PLATFORM_GET); @@ -7658,6 +7702,9 @@ dispose (GObject *object) g_clear_object (&priv->policy); } + nm_clear_g_source (&priv->connection_changed_on_idle_id); + nm_c_list_elem_free_all (&priv->connection_changed_on_idle_lst, g_object_unref); + if (priv->settings) { g_signal_handlers_disconnect_by_func (priv->settings, settings_startup_complete_changed, self); g_signal_handlers_disconnect_by_func (priv->settings, system_unmanaged_devices_changed_cb, self); |