merge: fix devices not re-activating when connections are downed (rh #1033187)

This commit is contained in:
Dan Williams
2013-12-12 14:55:33 -06:00
3 changed files with 44 additions and 21 deletions

View File

@@ -86,6 +86,7 @@ enum {
}; };
static void check_master_ready (NMActiveConnection *self); static void check_master_ready (NMActiveConnection *self);
static void _device_cleanup (NMActiveConnectionPrivate *priv);
/****************************************************************/ /****************************************************************/
@@ -146,10 +147,11 @@ nm_active_connection_set_state (NMActiveConnection *self,
} }
if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) { if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
/* Device is no longer relevant when deactivated; emit property change /* Device is no longer relevant when deactivated. So remove it and
* notification so clients re-read the value, which will be NULL due to * emit property change notification so clients re-read the value,
* conditions in get_property(). * which will be NULL due to conditions in get_property().
*/ */
_device_cleanup (priv);
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES); g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES);
} }
} }
@@ -726,6 +728,17 @@ get_property (GObject *object, guint prop_id,
} }
} }
static void
_device_cleanup (NMActiveConnectionPrivate *priv)
{
if (priv->device_state_id) {
g_assert (priv->device);
g_signal_handler_disconnect (priv->device, priv->device_state_id);
priv->device_state_id = 0;
}
g_clear_object (&priv->device);
}
static void static void
dispose (GObject *object) dispose (GObject *object)
{ {
@@ -743,12 +756,7 @@ dispose (GObject *object)
g_clear_object (&priv->connection); g_clear_object (&priv->connection);
if (priv->device_state_id) { _device_cleanup (priv);
g_assert (priv->device);
g_signal_handler_disconnect (priv->device, priv->device_state_id);
priv->device_state_id = 0;
}
g_clear_object (&priv->device);
if (priv->master) { if (priv->master) {
g_signal_handlers_disconnect_by_func (priv->master, g_signal_handlers_disconnect_by_func (priv->master,

View File

@@ -1454,7 +1454,6 @@ device_state_changed (NMDevice *device,
} }
nm_connection_clear_secrets (connection); nm_connection_clear_secrets (connection);
} }
schedule_activate_check (policy, device, 3);
break; break;
case NM_DEVICE_STATE_ACTIVATED: case NM_DEVICE_STATE_ACTIVATED:
if (connection) { if (connection) {
@@ -1628,13 +1627,20 @@ typedef struct {
} DeviceSignalId; } DeviceSignalId;
static void static void
_connect_device_signal (NMPolicy *policy, NMDevice *device, const char *name, gpointer callback) _connect_device_signal (NMPolicy *policy,
NMDevice *device,
const char *name,
gpointer callback,
gboolean after)
{ {
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
DeviceSignalId *data; DeviceSignalId *data;
data = g_slice_new0 (DeviceSignalId); data = g_slice_new0 (DeviceSignalId);
g_assert (data); g_assert (data);
if (after)
data->id = g_signal_connect_after (device, name, callback, policy);
else
data->id = g_signal_connect (device, name, callback, policy); data->id = g_signal_connect (device, name, callback, policy);
data->device = device; data->device = device;
priv->dev_ids = g_slist_prepend (priv->dev_ids, data); priv->dev_ids = g_slist_prepend (priv->dev_ids, data);
@@ -1645,22 +1651,23 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data)
{ {
NMPolicy *policy = (NMPolicy *) user_data; NMPolicy *policy = (NMPolicy *) user_data;
_connect_device_signal (policy, device, "state-changed", device_state_changed); /* Connect state-changed with _after, so that the handler is invoked after other handlers. */
_connect_device_signal (policy, device, NM_DEVICE_IP4_CONFIG_CHANGED, device_ip4_config_changed); _connect_device_signal (policy, device, "state-changed", device_state_changed, TRUE);
_connect_device_signal (policy, device, NM_DEVICE_IP6_CONFIG_CHANGED, device_ip6_config_changed); _connect_device_signal (policy, device, NM_DEVICE_IP4_CONFIG_CHANGED, device_ip4_config_changed, FALSE);
_connect_device_signal (policy, device, "notify::" NM_DEVICE_AUTOCONNECT, device_autoconnect_changed); _connect_device_signal (policy, device, NM_DEVICE_IP6_CONFIG_CHANGED, device_ip6_config_changed, FALSE);
_connect_device_signal (policy, device, "notify::" NM_DEVICE_AUTOCONNECT, device_autoconnect_changed, FALSE);
switch (nm_device_get_device_type (device)) { switch (nm_device_get_device_type (device)) {
case NM_DEVICE_TYPE_WIFI: case NM_DEVICE_TYPE_WIFI:
_connect_device_signal (policy, device, "access-point-added", wireless_networks_changed); _connect_device_signal (policy, device, "access-point-added", wireless_networks_changed, FALSE);
_connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed); _connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed, FALSE);
break; break;
case NM_DEVICE_TYPE_WIMAX: case NM_DEVICE_TYPE_WIMAX:
_connect_device_signal (policy, device, "nsp-added", nsps_changed); _connect_device_signal (policy, device, "nsp-added", nsps_changed, FALSE);
_connect_device_signal (policy, device, "nsp-removed", nsps_changed); _connect_device_signal (policy, device, "nsp-removed", nsps_changed, FALSE);
break; break;
case NM_DEVICE_TYPE_MODEM: case NM_DEVICE_TYPE_MODEM:
_connect_device_signal (policy, device, "enable-changed", modem_enabled_changed); _connect_device_signal (policy, device, "enable-changed", modem_enabled_changed, FALSE);
break; break;
default: default:
break; break;

View File

@@ -206,6 +206,12 @@ nm_vpn_connection_set_vpn_state (NMVPNConnection *connection,
old_vpn_state = priv->vpn_state; old_vpn_state = priv->vpn_state;
priv->vpn_state = vpn_state; priv->vpn_state = vpn_state;
/* The device gets destroyed by active connection when it enters
* the deactivated state, so we need to ref it for usage below.
*/
if (parent_dev)
g_object_ref (parent_dev);
/* Update active connection base class state */ /* Update active connection base class state */
nm_active_connection_set_state (NM_ACTIVE_CONNECTION (connection), nm_active_connection_set_state (NM_ACTIVE_CONNECTION (connection),
ac_state_from_vpn_state (vpn_state)); ac_state_from_vpn_state (vpn_state));
@@ -271,6 +277,8 @@ nm_vpn_connection_set_vpn_state (NMVPNConnection *connection,
} }
g_object_unref (connection); g_object_unref (connection);
if (parent_dev)
g_object_unref (parent_dev);
} }
static void static void