authd: refcounting fixes
This commit is contained in:
parent
34f65493cd
commit
45e6c74631
1 changed files with 24 additions and 12 deletions
|
@ -166,33 +166,36 @@ cancel_providers(struct auth_client *auth)
|
||||||
|
|
||||||
RB_DICTIONARY_FOREACH(provider, &iter, auth_providers)
|
RB_DICTIONARY_FOREACH(provider, &iter, auth_providers)
|
||||||
{
|
{
|
||||||
if(provider->cancel && is_provider_running(auth, provider->id))
|
if(provider->cancel != NULL && is_provider_running(auth, provider->id))
|
||||||
/* Cancel if required */
|
/* Cancel if required */
|
||||||
provider->cancel(auth);
|
provider->cancel(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auth->refcount = 0;
|
||||||
rb_dictionary_delete(auth_clients, RB_UINT_TO_POINTER(auth->cid));
|
rb_dictionary_delete(auth_clients, RB_UINT_TO_POINTER(auth->cid));
|
||||||
rb_free(auth->data);
|
rb_free(auth->data);
|
||||||
rb_free(auth);
|
rb_free(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Provider is done - WARNING: do not use auth instance after calling! */
|
/* Provider is done
|
||||||
|
* WARNING: do not use auth instance after calling! */
|
||||||
void
|
void
|
||||||
provider_done(struct auth_client *auth, uint32_t id)
|
provider_done(struct auth_client *auth, uint32_t id)
|
||||||
{
|
{
|
||||||
rb_dictionary_iter iter;
|
rb_dictionary_iter iter;
|
||||||
struct auth_provider *provider;
|
struct auth_provider *provider;
|
||||||
|
|
||||||
set_provider_done(auth, id);
|
if(auth->refcount == 1 && !auth->providers_starting)
|
||||||
|
|
||||||
if(!auth->refcount)
|
|
||||||
{
|
{
|
||||||
if(!auth->providers_starting)
|
/* Providers aren't being executed and refcount is 1 (last provider), accept */
|
||||||
/* Providers aren't being executed and refcount is 0, accept */
|
accept_client(auth, id);
|
||||||
accept_client(auth, -1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_provider_done(auth, id);
|
||||||
|
|
||||||
|
/* It's safe to use auth below, since refcount will be > 0, per above
|
||||||
|
* Thus the object will still be live */
|
||||||
RB_DICTIONARY_FOREACH(provider, &iter, auth_providers)
|
RB_DICTIONARY_FOREACH(provider, &iter, auth_providers)
|
||||||
{
|
{
|
||||||
if(provider->completed != NULL && is_provider_running(auth, provider->id))
|
if(provider->completed != NULL && is_provider_running(auth, provider->id))
|
||||||
|
@ -201,10 +204,12 @@ provider_done(struct auth_client *auth, uint32_t id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reject a client - WARNING: do not use auth instance after calling! */
|
/* Reject a client
|
||||||
|
* WARNING: do not use auth instance after calling! */
|
||||||
void
|
void
|
||||||
reject_client(struct auth_client *auth, uint32_t id, const char *data, const char *fmt, ...)
|
reject_client(struct auth_client *auth, uint32_t id, const char *data, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
unsigned int refcount = auth->refcount;
|
||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
@ -225,16 +230,23 @@ reject_client(struct auth_client *auth, uint32_t id, const char *data, const cha
|
||||||
data, buf);
|
data, buf);
|
||||||
|
|
||||||
set_provider_done(auth, id);
|
set_provider_done(auth, id);
|
||||||
|
if(--refcount > 0)
|
||||||
|
/* We have providers remaining, let them clean up */
|
||||||
cancel_providers(auth);
|
cancel_providers(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accept a client, cancel outstanding providers if any - WARNING: do nto use auth instance after calling! */
|
/* Accept a client, cancel outstanding providers if any
|
||||||
|
* WARNING: do not use auth instance after calling! */
|
||||||
void
|
void
|
||||||
accept_client(struct auth_client *auth, uint32_t id)
|
accept_client(struct auth_client *auth, uint32_t id)
|
||||||
{
|
{
|
||||||
|
unsigned int refcount = auth->refcount;
|
||||||
|
|
||||||
rb_helper_write(authd_helper, "A %x %s %s", auth->cid, auth->username, auth->hostname);
|
rb_helper_write(authd_helper, "A %x %s %s", auth->cid, auth->username, auth->hostname);
|
||||||
|
|
||||||
set_provider_done(auth, id);
|
set_provider_done(auth, id);
|
||||||
|
if(--refcount > 0)
|
||||||
|
/* We have providers remaining, let them clean up */
|
||||||
cancel_providers(auth);
|
cancel_providers(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue