core: create virtual device on settings changes in idle handler

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.
This commit is contained in:
Thomas Haller 2019-06-30 10:33:28 +02:00
parent 42a034812a
commit c163207b07

View file

@ -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);