diff options
author | Thomas Haller <thaller@redhat.com> | 2018-04-09 12:36:06 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-04-13 09:09:46 +0200 |
commit | 290d02536c237cd14f187611e72e5fc0b52c81a7 (patch) | |
tree | fe8555c8e4e2275686e25ff2df87babb5b8e5a9d | |
parent | 50b74731f668067d445a28d7e545a169bf9d25c8 (diff) | |
download | NetworkManager-290d02536c237cd14f187611e72e5fc0b52c81a7.tar.gz |
auth-chain: avoid another idle-call when auth-request completes
NMAuthChain schedules (possibly) multiple authentication requests.
When they all complete, it will once invoke the result-callback.
There is no need to schedule this result-callback on another idle-handler,
because nm_auth_manager_polkit_authority_check_authorization() should guarantee
to invoke the callback never-synchronously and on a clean call-stack (to avoid
problems with re-entrancy). At that point, NMAuthChain does not need to
delay this further.
-rw-r--r-- | src/nm-auth-manager.c | 3 | ||||
-rw-r--r-- | src/nm-auth-utils.c | 27 |
2 files changed, 14 insertions, 16 deletions
diff --git a/src/nm-auth-manager.c b/src/nm-auth-manager.c index 003d997505..d1b8d91e1d 100644 --- a/src/nm-auth-manager.c +++ b/src/nm-auth-manager.c @@ -240,6 +240,9 @@ _call_check_authorization (CheckAuthData *data) data->dbus_parameters = NULL; } +/* + * @callback must never be invoked synchronously. + */ void nm_auth_manager_polkit_authority_check_authorization (NMAuthManager *self, NMAuthSubject *subject, diff --git a/src/nm-auth-utils.c b/src/nm-auth-utils.c index da5843b0bf..3c5440eb2b 100644 --- a/src/nm-auth-utils.c +++ b/src/nm-auth-utils.c @@ -44,8 +44,6 @@ struct NMAuthChain { NMAuthChainResultFunc done_func; gpointer user_data; - guint idle_id; - guint32 refcount; bool done:1; @@ -209,16 +207,15 @@ nm_auth_chain_get_subject (NMAuthChain *self) /*****************************************************************************/ static gboolean -auth_chain_finish (gpointer user_data) +auth_chain_finish (NMAuthChain *self) { - NMAuthChain *self = user_data; - - self->idle_id = 0; self->done = TRUE; /* Ensure we stay alive across the callback */ + nm_assert (self->refcount == 1); self->refcount++; self->done_func (self, NULL, self->context, self->user_data); + nm_assert (NM_IN_SET (self->refcount, 1, 2)); nm_auth_chain_destroy (self); return FALSE; } @@ -232,14 +229,14 @@ auth_call_complete (AuthCall *call) self = call->chain; - c_list_unlink (&call->auth_call_lst); + nm_assert (!self->done); + + auth_call_free (call); if (c_list_is_empty (&self->auth_call_lst_head)) { - nm_assert (!self->idle_id && !self->done); - self->idle_id = g_idle_add (auth_chain_finish, self); + /* we are on an idle-handler or a clean call-stack (non-reentrant). */ + auth_chain_finish (self); } - - auth_call_free (call); } static gboolean @@ -307,10 +304,10 @@ nm_auth_chain_add_call (NMAuthChain *self, NMAuthManager *auth_manager = nm_auth_manager_get (); g_return_if_fail (self); - g_return_if_fail (permission && *permission); g_return_if_fail (self->subject); + g_return_if_fail (!self->done); + g_return_if_fail (permission && *permission); g_return_if_fail (nm_auth_subject_is_unix_process (self->subject) || nm_auth_subject_is_internal (self->subject)); - g_return_if_fail (!self->idle_id && !self->done); call = g_slice_new0 (AuthCall); call->chain = self; @@ -412,13 +409,11 @@ nm_auth_chain_destroy (NMAuthChain *self) AuthCall *call; g_return_if_fail (self); - g_return_if_fail (self->refcount > 0); + g_return_if_fail (NM_IN_SET (self->refcount, 1, 2)); if (--self->refcount > 0) return; - nm_clear_g_source (&self->idle_id); - nm_clear_g_object (&self->subject); nm_clear_g_object (&self->context); |