From 1e90ef2043884c032df93a19381528e7f0f5645a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 19 Jan 2016 11:33:33 +0100 Subject: [PATCH] device: remove unrealized device without connections on idle handler Emitting the NM_DEVICE_REMOVED signal can cause the destruction of the device, thus it should be emitted on an idle handler. --- src/devices/nm-device.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index b6eb96ca0f..d2127fffc3 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -364,6 +364,8 @@ typedef struct _NMDevicePrivate { NMConnectionProvider *con_provider; NMLldpListener *lldp_listener; + + guint check_delete_unrealized_id; } NMDevicePrivate; static gboolean nm_device_set_ip4_config (NMDevice *self, @@ -1997,14 +1999,36 @@ unrealize_notify (NMDevice *self) * implementation. */ } -static void -available_connection_check_delete_unrealized (NMDevice *self) +static gboolean +available_connection_check_delete_unrealized_on_idle (gpointer user_data) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMDevice *self = user_data; + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE); + + priv = NM_DEVICE_GET_PRIVATE (self); + + priv->check_delete_unrealized_id = 0; if ( g_hash_table_size (priv->available_connections) == 0 && !nm_device_is_real (self)) - g_signal_emit_by_name (self, NM_DEVICE_REMOVED); + g_signal_emit (self, signals[REMOVED], 0); + + return G_SOURCE_REMOVE; +} + +static void +available_connection_check_delete_unrealized (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + /* always rescheadule the remove signal. */ + nm_clear_g_source (&priv->check_delete_unrealized_id); + + if ( g_hash_table_size (priv->available_connections) == 0 + && !nm_device_is_real (self)) + priv->check_delete_unrealized_id = g_idle_add (available_connection_check_delete_unrealized_on_idle, self); } /** @@ -2104,7 +2128,6 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) /* Garbage-collect unneeded unrealized devices. */ nm_device_recheck_available_connections (self); - available_connection_check_delete_unrealized (self); return TRUE; } @@ -9153,6 +9176,8 @@ nm_device_recheck_available_connections (NMDevice *self) _signal_available_connections_changed (self); } + + available_connection_check_delete_unrealized (self); } /** @@ -10593,6 +10618,8 @@ dispose (GObject *object) nm_clear_g_source (&priv->recheck_assume_id); nm_clear_g_source (&priv->recheck_available.call_id); + nm_clear_g_source (&priv->check_delete_unrealized_id); + link_disconnect_action_cancel (self); if (priv->con_provider) {