summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2014-02-13 14:45:25 -0500
committerDan Winship <danw@gnome.org>2014-02-17 14:57:15 -0500
commit4f0c70e94534abafde6a0459af74b68a7da724d9 (patch)
tree51ef2b2382ba81bf36166801050fdf94f22bd564
parent93285054ae5ef290d879a753f88824b5027e9c8a (diff)
downloadNetworkManager-4f0c70e94534abafde6a0459af74b68a7da724d9.tar.gz
core: don't recursively schedule an autoactivate check on a device
NMPolicy's auto_activate_device() was immediately removing the device from priv->pending_activation_checks, which meant that if nm_manager_activate_connection() had some side effect that would cause schedule_activation_check() to be called again, another auto-activation check could be queued while the first was still in progress (causing a warning). Fix this by not removing the device from the list until the activation attempt is complete. This requires some additional minor changes to correctly handle the possibility of remove_device() being triggered as a side effect of nm_manager_activate_connection(). Also merge activate_data_new() into schedule_activation_check() so that all the "start an auto-activation" code is in one place.
-rw-r--r--src/nm-policy.c56
1 files changed, 25 insertions, 31 deletions
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 142cf6521a..90fbc36d8d 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -937,12 +937,14 @@ typedef struct {
static void
activate_data_free (ActivateData *data)
{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (data->policy);
+
nm_device_remove_pending_action (data->device, "autoactivate");
+ priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data);
if (data->autoactivate_id)
g_source_remove (data->autoactivate_id);
g_object_unref (data->device);
- memset (data, 0, sizeof (*data));
g_free (data);
}
@@ -961,7 +963,6 @@ auto_activate_device (gpointer user_data)
priv = NM_POLICY_GET_PRIVATE (policy);
data->autoactivate_id = 0;
- priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data);
// FIXME: if a device is already activating (or activated) with a connection
// but another connection now overrides the current one for that device,
@@ -1014,21 +1015,6 @@ auto_activate_device (gpointer user_data)
}
static ActivateData *
-activate_data_new (NMPolicy *policy, NMDevice *device)
-{
- ActivateData *data;
-
- data = g_malloc0 (sizeof (ActivateData));
- data->policy = policy;
- data->device = g_object_ref (device);
- data->autoactivate_id = g_idle_add (auto_activate_device, data);
-
- nm_device_add_pending_action (device, "autoactivate");
-
- return data;
-}
-
-static ActivateData *
find_pending_activation (GSList *list, NMDevice *device)
{
GSList *iter;
@@ -1226,20 +1212,33 @@ schedule_activate_check (NMPolicy *policy, NMDevice *device)
if (!nm_device_autoconnect_allowed (device))
return;
- /* If the device already has an activation in-progress or waiting for
- * authentication, don't start an auto-activation for it.
- */
+ if (find_pending_activation (priv->pending_activation_checks, device))
+ return;
+
active_connections = nm_manager_get_active_connections (priv->manager);
for (iter = active_connections; iter; iter = iter->next) {
if (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (iter->data)) == device)
return;
}
- /* Schedule an auto-activation if there isn't one already for this device */
- if (find_pending_activation (priv->pending_activation_checks, device) == NULL) {
- data = activate_data_new (policy, device);
- priv->pending_activation_checks = g_slist_append (priv->pending_activation_checks, data);
- }
+ nm_device_add_pending_action (device, "autoactivate");
+
+ data = g_malloc0 (sizeof (ActivateData));
+ data->policy = policy;
+ data->device = g_object_ref (device);
+ data->autoactivate_id = g_idle_add (auto_activate_device, data);
+ priv->pending_activation_checks = g_slist_append (priv->pending_activation_checks, data);
+}
+
+static void
+clear_pending_activate_check (NMPolicy *policy, NMDevice *device)
+{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
+ ActivateData *data;
+
+ data = find_pending_activation (priv->pending_activation_checks, device);
+ if (data && data->autoactivate_id)
+ activate_data_free (data);
}
static gboolean
@@ -1676,15 +1675,10 @@ device_removed (NMManager *manager, NMDevice *device, gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
- ActivateData *tmp;
GSList *iter;
/* Clear any idle callbacks for this device */
- tmp = find_pending_activation (priv->pending_activation_checks, device);
- if (tmp) {
- priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, tmp);
- activate_data_free (tmp);
- }
+ clear_pending_activate_check (policy, device);
/* Clear any signal handlers for this device */
iter = priv->dev_ids;