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:
@@ -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);
|
||||
|
Reference in New Issue
Block a user