summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-06-30 10:33:28 +0200
committerThomas Haller <thaller@redhat.com>2019-07-01 09:05:54 +0200
commit79878fc9bd9dbe3d5fc9137e075dcaf3af21bd23 (patch)
treec6fd3b53b42077c41681d79f343682711c9d0054
parentd6ce3776a75045926c61ee6c9e5ca1e4649d690a (diff)
downloadNetworkManager-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.c51
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);