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
This commit is contained in:
Dan Williams 2014-11-07 16:47:13 -06:00
parent dde8e703f8
commit 14537c71d8
2 changed files with 14 additions and 11 deletions

View file

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

View file

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