core: make ActiveConnection emit StateChanged a bit later

We need to make sure StateChanged goes on the D-Bus only after the
policy is done dealing with the state change internally.

This is done so that we can be sure the DNS changes are committed at the
time "nmcli c up" returns.

https://bugzilla.redhat.com/show_bug.cgi?id=2006677
This commit is contained in:
Lubomir Rintel 2021-10-18 12:43:17 +02:00
parent c75b7dd893
commit 4ae846b9c6

View file

@ -31,14 +31,15 @@ typedef struct _NMActiveConnectionPrivate {
char *pending_activation_id;
NMActivationStateFlags state_flags;
NMActivationStateFlags state_flags;
NMActiveConnectionState state;
NMActiveConnectionStateReason reason;
NMActiveConnectionState state;
bool is_default : 1;
bool is_default6 : 1;
bool state_set : 1;
bool vpn : 1;
bool master_ready : 1;
bool is_default : 1;
bool is_default6 : 1;
bool state_set : 1;
bool vpn : 1;
bool master_ready : 1;
NMActivationType activation_type : 3;
@ -226,16 +227,28 @@ nm_active_connection_get_state(NMActiveConnection *self)
return NM_ACTIVE_CONNECTION_GET_PRIVATE(self)->state;
}
static void
emit_state_changed(NMActiveConnection *self, guint state, guint reason)
static int
dbus_emit_state_changed(gpointer user_data)
{
NMActiveConnection * self = NM_ACTIVE_CONNECTION(user_data);
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE(self);
nm_dbus_object_emit_signal(NM_DBUS_OBJECT(self),
&interface_info_active_connection,
&signal_info_state_changed,
"(uu)",
(guint32) state,
(guint32) reason);
(guint32) priv->state,
(guint32) priv->reason);
g_object_unref(self);
return G_SOURCE_REMOVE;
}
static void
emit_state_changed(NMActiveConnection *self, guint state, guint reason)
{
g_signal_emit(self, signals[STATE_CHANGED], 0, state, reason);
g_idle_add(dbus_emit_state_changed, g_object_ref(self));
}
void
@ -250,6 +263,7 @@ nm_active_connection_set_state(NMActiveConnection * self,
g_return_if_fail(priv->state != NM_ACTIVE_CONNECTION_STATE_DEACTIVATED
|| new_state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
priv->reason = reason;
if (priv->state == new_state)
return;
@ -272,8 +286,8 @@ nm_active_connection_set_state(NMActiveConnection * self,
old_state = priv->state;
priv->state = new_state;
priv->state_set = TRUE;
emit_state_changed(self, new_state, reason);
_notify(self, PROP_STATE);
emit_state_changed(self, new_state, reason);
check_master_ready(self);