From 14537c71d8a28f9805bd410f2df475db8b4aa6f6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 7 Nov 2014 16:47:13 -0600 Subject: [PATCH] libnm-core: emit added/removed signals before property change notifications Because internal objects do some processing/setup in the various _added class signal handlers, they need to be emitted before property change notifications. Otherwise it leads to situations where external objects that listen to NMClient property changes will be called before internal processing has been completed. Specifically, NMRemoteSettings uses connection_added() to check connection visibility and assign the new connection to one of two internal arrays. If a client got a property notification for NMClient::connections before NMRemoteSettings can process the new connection, then nm_client_get_connections() will return an empty array because NMRemoteSettings hasn't had the chance to add the new connection to priv->visible yet, which is done in NMRemoteSettings::connection_added(). Fixes:Beaker:NetworkManager_Test240_nmtui_general_realtime_refresh_edit_screen --- libnm/nm-object.c | 21 ++++++++++++--------- libnm/tests/test-nm-client.c | 4 ++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libnm/nm-object.c b/libnm/nm-object.c index 2023a74fa0..4bc82b8b1e 100644 --- a/libnm/nm-object.c +++ b/libnm/nm-object.c @@ -209,15 +209,9 @@ deferred_notify_cb (gpointer data) g_object_ref (object); - /* Emit property change notifications first */ - for (iter = props; iter; iter = g_slist_next (iter)) { - NotifyItem *item = iter->data; - - if (item->property) - g_object_notify (G_OBJECT (object), item->property); - } - - /* And added/removed signals second */ + /* Emit added/removed signals first since some of our internal objects + * use the added/removed signals for new object processing. + */ for (iter = props; iter; iter = g_slist_next (iter)) { NotifyItem *item = iter->data; char buf[50]; @@ -243,6 +237,15 @@ deferred_notify_cb (gpointer data) g_signal_emit_by_name (object, buf, item->changed); } } + + /* Emit property change notifications second */ + for (iter = props; iter; iter = g_slist_next (iter)) { + NotifyItem *item = iter->data; + + if (item->property) + g_object_notify (G_OBJECT (object), item->property); + } + g_object_unref (object); g_slist_free_full (props, (GDestroyNotify) notify_item_free); diff --git a/libnm/tests/test-nm-client.c b/libnm/tests/test-nm-client.c index 867a27933b..ada1f6f4a7 100644 --- a/libnm/tests/test-nm-client.c +++ b/libnm/tests/test-nm-client.c @@ -192,8 +192,8 @@ test_device_added_signal_after_init (void) g_signal_handlers_disconnect_by_func (client, device_sai_added_cb, &result); g_signal_handlers_disconnect_by_func (client, devices_sai_notify_cb, &result); - g_assert ((result & NOTIFY_MASK) == NOTIFY_FIRST); - g_assert ((result & SIGNAL_MASK) == SIGNAL_SECOND); + g_assert ((result & SIGNAL_MASK) == SIGNAL_FIRST); + g_assert ((result & NOTIFY_MASK) == NOTIFY_SECOND); devices = nm_client_get_devices (client); g_assert (devices);