settings: refactor call_id type of async functions for NMAgentManager, NMSettingsConnection and NMActRequest

Instead of having the call_id of type guint32, make it an (opaque)
pointer type.

This has the advantage of strong typing and avoids the possiblity
of reusing an invalid integer (or overflow of the call-id counter).

OTOH, it has the disadvantage, that after a call_id is disposed,
it might be reused for future invocations (because malloc might
reuse the memory).

In fact, it is always an error to use a call_id that is already
completed. This commit also adds assertions to the cancel() calls
that the provided call_id is a pending call. Hence, such a bug
will be uncovered by assertions (that only might not tigger in
certain unlikely cases where a call-id got reused).

Note that for NMAgentManager, save_secrets() and delete_secrets()
both returned a call_id. But they didn't also provide a callback when
the operation completes. So the user trying to cancel such a call,
cannot know whether the operation is still in process and he cannot
avoid triggering an assertion.
Fix that by not returning a call-id for these operations. No caller
cared about it anyway.

For NMSettingsConnection, also track the internally scheduled requests
for so that we can cancel them on dispose.
This commit is contained in:
Thomas Haller
2015-09-02 22:43:04 +02:00
parent 40eda71dc6
commit 21fd5fa0ab
11 changed files with 202 additions and 163 deletions

View File

@@ -75,16 +75,18 @@ nm_act_request_get_connection (NMActRequest *req)
/*******************************************************************/
typedef struct {
struct _NMActRequestGetSecretsCallId {
NMActRequest *self;
guint32 call_id;
NMSettingsConnectionCallId call_id_s;
NMActRequestSecretsFunc callback;
gpointer callback_data;
} GetSecretsInfo;
};
typedef struct _NMActRequestGetSecretsCallId GetSecretsInfo;
static void
get_secrets_cb (NMSettingsConnection *connection,
guint32 call_id,
NMSettingsConnectionCallId call_id_s,
const char *agent_username,
const char *setting_name,
GError *error,
@@ -93,14 +95,14 @@ get_secrets_cb (NMSettingsConnection *connection,
GetSecretsInfo *info = user_data;
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (info->self);
g_return_if_fail (info->call_id == call_id);
g_return_if_fail (info->call_id_s == call_id_s);
priv->secrets_calls = g_slist_remove (priv->secrets_calls, info);
info->callback (info->self, call_id, NM_CONNECTION (connection), error, info->callback_data);
info->callback (info->self, info, NM_CONNECTION (connection), error, info->callback_data);
g_free (info);
}
guint32
NMActRequestGetSecretsCallId
nm_act_request_get_secrets (NMActRequest *self,
const char *setting_name,
NMSecretAgentGetSecretsFlags flags,
@@ -110,7 +112,7 @@ nm_act_request_get_secrets (NMActRequest *self,
{
NMActRequestPrivate *priv;
GetSecretsInfo *info;
guint32 call_id;
NMSettingsConnectionCallId call_id_s;
NMConnection *connection;
const char *hints[2] = { hint, NULL };
@@ -128,25 +130,25 @@ nm_act_request_get_secrets (NMActRequest *self,
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED;
connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self));
call_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (connection),
nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)),
setting_name,
flags,
hints,
get_secrets_cb,
info,
NULL);
if (call_id > 0) {
info->call_id = call_id;
call_id_s = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (connection),
nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)),
setting_name,
flags,
hints,
get_secrets_cb,
info,
NULL);
if (call_id_s) {
info->call_id_s = call_id_s;
priv->secrets_calls = g_slist_append (priv->secrets_calls, info);
} else
g_free (info);
return call_id;
return info;
}
void
nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id)
nm_act_request_cancel_secrets (NMActRequest *self, NMActRequestGetSecretsCallId call_id)
{
NMActRequestPrivate *priv;
NMConnection *connection;
@@ -154,24 +156,25 @@ nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id)
g_return_if_fail (self);
g_return_if_fail (NM_IS_ACT_REQUEST (self));
g_return_if_fail (call_id > 0);
g_return_if_fail (call_id);
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self));
for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
GetSecretsInfo *info = iter->data;
/* Remove the matching info */
if (info->call_id == call_id) {
if (info == call_id) {
priv->secrets_calls = g_slist_remove_link (priv->secrets_calls, iter);
g_slist_free (iter);
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), call_id);
connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self));
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), info->call_id_s);
g_free (info);
break;
return;
}
}
g_return_if_reached ();
}
/********************************************************************/
@@ -444,7 +447,7 @@ dispose (GObject *object)
for (iter = priv->secrets_calls; connection && iter; iter = g_slist_next (iter)) {
GetSecretsInfo *info = iter->data;
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), info->call_id);
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), info->call_id_s);
g_free (info);
}
g_slist_free (priv->secrets_calls);