summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2012-12-03 14:41:28 -0500
committerDan Winship <danw@gnome.org>2012-12-03 15:19:53 -0500
commit829234fd8d79bc3cae14022c9c56d0141869ecd3 (patch)
tree77f449d993b8c73eb73dcd73ce9b31cf7169783b
parent445e8755bc96c670950cd002980dbddead1c2fa4 (diff)
downloadNetworkManager-829234fd8d79bc3cae14022c9c56d0141869ecd3.tar.gz
libnm-glib: more NMDevice::state-changed fixes
Ensure that NMDevice::state-changed signals don't get emitted out of order, and ensure that nm_device_get_state() from a ::state-changed handler always returns new_state.
-rw-r--r--libnm-glib/nm-device.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c
index 46a5d97b5b..22e2844cfc 100644
--- a/libnm-glib/nm-device.c
+++ b/libnm-glib/nm-device.c
@@ -80,6 +80,7 @@ typedef struct {
NMIP6Config *ip6_config;
NMDHCP6Config *dhcp6_config;
NMDeviceState state;
+ NMDeviceState last_seen_state;
NMDeviceStateReason reason;
NMActiveConnection *active_connection;
@@ -197,10 +198,24 @@ device_state_change_reloaded (GObject *object,
gpointer user_data)
{
NMDevice *self = NM_DEVICE (object);
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
StateChangeData *data = user_data;
_nm_object_reload_properties_finish (NM_OBJECT (object), result, NULL);
+ /* If the device changes state several times in rapid succession, then we'll
+ * queue several reload_properties() calls, and there's no guarantee that
+ * they'll finish in the right order. In that case, only emit the signal
+ * for the last one.
+ */
+ if (priv->last_seen_state != data->new_state)
+ return;
+
+ /* Ensure that nm_device_get_state() will return the right value even if
+ * we haven't processed the corresponding PropertiesChanged yet.
+ */
+ priv->state = data->new_state;
+
g_signal_emit (self, signals[STATE_CHANGED], 0,
data->new_state, data->old_state, data->reason);
g_slice_free (StateChangeData, data);
@@ -213,6 +228,9 @@ device_state_changed (DBusGProxy *proxy,
NMDeviceStateReason reason,
gpointer user_data)
{
+ NMDevice *self = NM_DEVICE (user_data);
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
if (old_state != new_state) {
StateChangeData *data;
@@ -221,6 +239,8 @@ device_state_changed (DBusGProxy *proxy,
* in the process of asynchronously reading the new values.
* Wait for that to finish before emitting the signal.
*/
+ priv->last_seen_state = new_state;
+
data = g_slice_new (StateChangeData);
data->old_state = old_state;
data->new_state = new_state;