libnm-glib: update properties before NMDevice:state-changed

Because object-valued properties (like ip4-config) get reloaded
asynchronously when they change, we will still have out-of-date values
for them cached at the point when we get the StateChanged signal from
the daemon. Work around this by manually reloading all properties
before emitting the client-side signal.

Also, fix a dumb bug in NMObject...
This commit is contained in:
Dan Winship 2012-08-29 14:14:26 -04:00
parent de763a42ec
commit 1eaf919bc6
2 changed files with 35 additions and 10 deletions

View file

@ -184,6 +184,27 @@ register_properties (NMDevice *device)
property_info);
}
typedef struct {
NMDeviceState old_state;
NMDeviceState new_state;
NMDeviceStateReason reason;
} StateChangeData;
static void
device_state_change_reloaded (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
NMDevice *self = NM_DEVICE (object);
StateChangeData *data = user_data;
_nm_object_reload_properties_finish (NM_OBJECT (object), result, NULL);
g_signal_emit (self, signals[STATE_CHANGED], 0,
data->new_state, data->old_state, data->reason);
g_slice_free (StateChangeData, data);
}
static void
device_state_changed (DBusGProxy *proxy,
NMDeviceState new_state,
@ -191,17 +212,21 @@ device_state_changed (DBusGProxy *proxy,
NMDeviceStateReason reason,
gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
if (old_state != new_state) {
/* Update state here since the PropertyChanged signal for state
* might come in a bit later, but a client might ask for the
* state via nm_device_get_state() as a result of this signal.
* When the PC signal does come in that will trigger the glib
* property notify signal so we don't need to do that here.
StateChangeData *data;
/* Our object-valued properties (eg, ip4_config) will still
* have their old values at this point, because NMObject is
* in the process of asynchronously reading the new values.
* Wait for that to finish before emitting the signal.
*/
NM_DEVICE_GET_PRIVATE (self)->state = new_state;
g_signal_emit (self, signals[STATE_CHANGED], 0, new_state, old_state, reason);
data = g_slice_new (StateChangeData);
data->old_state = old_state;
data->new_state = new_state;
data->reason = reason;
_nm_object_reload_properties_async (NM_OBJECT (user_data),
device_state_change_reloaded,
data);
}
}

View file

@ -1318,7 +1318,7 @@ reload_complete (NMObject *object)
priv->reload_error = NULL;
for (iter = results; iter; iter = iter->next) {
simple = results->data;
simple = iter->data;
if (error)
g_simple_async_result_set_from_error (simple, error);