mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
agent: Fix detection of exit of scdaemon.
* agent/call-scd.c (start_scd): Acquire START_SCD_LOCK for SCD_LOCAL_LIST. Move common case code to fast path. Release START_SCD_LOCK before calling unlock_scd. When new CTX is allocated, clear INVALID flag. (agent_reset_scd): Serialize the access to SCD_LOCAL_LIST by START_SCD_LOCK. -- GnuPG-bug-id: 4377 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
8d4af54ddd
commit
2abad7585a
@ -303,33 +303,19 @@ start_scd (ctrl_t ctrl)
|
||||
if (opt.disable_scdaemon)
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
|
||||
/* If this is the first call for this session, setup the local data
|
||||
structure. */
|
||||
if (!ctrl->scd_local)
|
||||
if (ctrl->scd_local && ctrl->scd_local->ctx)
|
||||
{
|
||||
ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
|
||||
if (!ctrl->scd_local)
|
||||
return gpg_error_from_syserror ();
|
||||
ctrl->scd_local->next_local = scd_local_list;
|
||||
scd_local_list = ctrl->scd_local;
|
||||
ctrl->scd_local->in_use = 1;
|
||||
return 0; /* Okay, the context is fine. */
|
||||
}
|
||||
|
||||
if (ctrl->scd_local->in_use)
|
||||
if (ctrl->scd_local && ctrl->scd_local->in_use)
|
||||
{
|
||||
log_error ("start_scd: CTX is in use\n");
|
||||
return gpg_error (GPG_ERR_INTERNAL);
|
||||
}
|
||||
ctrl->scd_local->in_use = 1;
|
||||
|
||||
if (ctrl->scd_local->ctx)
|
||||
return 0; /* Okay, the context is fine. We used to test for an
|
||||
alive context here and do an disconnect. Now that we
|
||||
have a ticker function to check for it, it is easier
|
||||
not to check here but to let the connection run on an
|
||||
error instead. */
|
||||
|
||||
|
||||
/* We need to protect the following code. */
|
||||
/* We need to serialize the access to scd_local_list and primary_scd_ctx. */
|
||||
rc = npth_mutex_lock (&start_scd_lock);
|
||||
if (rc)
|
||||
{
|
||||
@ -338,6 +324,25 @@ start_scd (ctrl_t ctrl)
|
||||
return gpg_error (GPG_ERR_INTERNAL);
|
||||
}
|
||||
|
||||
/* If this is the first call for this session, setup the local data
|
||||
structure. */
|
||||
if (!ctrl->scd_local)
|
||||
{
|
||||
ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
|
||||
if (!ctrl->scd_local)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
rc = npth_mutex_unlock (&start_scd_lock);
|
||||
if (rc)
|
||||
log_error ("failed to release the start_scd lock: %s\n", strerror (rc));
|
||||
return err;
|
||||
}
|
||||
ctrl->scd_local->next_local = scd_local_list;
|
||||
scd_local_list = ctrl->scd_local;
|
||||
}
|
||||
|
||||
ctrl->scd_local->in_use = 1;
|
||||
|
||||
/* Check whether the pipe server has already been started and in
|
||||
this case either reuse a lingering pipe connection or establish a
|
||||
new socket based one. */
|
||||
@ -522,6 +527,10 @@ start_scd (ctrl_t ctrl)
|
||||
}
|
||||
|
||||
leave:
|
||||
rc = npth_mutex_unlock (&start_scd_lock);
|
||||
if (rc)
|
||||
log_error ("failed to release the start_scd lock: %s\n", strerror (rc));
|
||||
|
||||
xfree (abs_homedir);
|
||||
if (err)
|
||||
{
|
||||
@ -531,11 +540,9 @@ start_scd (ctrl_t ctrl)
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl->scd_local->invalid = 0;
|
||||
ctrl->scd_local->ctx = ctx;
|
||||
}
|
||||
rc = npth_mutex_unlock (&start_scd_lock);
|
||||
if (rc)
|
||||
log_error ("failed to release the start_scd lock: %s\n", strerror (rc));
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -554,15 +561,21 @@ agent_scd_check_running (void)
|
||||
a cleanup of resources used by the current connection. */
|
||||
int
|
||||
agent_reset_scd (ctrl_t ctrl)
|
||||
{
|
||||
int err = npth_mutex_lock (&start_scd_lock);
|
||||
|
||||
if (err)
|
||||
{
|
||||
log_error ("failed to acquire the start_scd lock: %s\n",
|
||||
strerror (err));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctrl->scd_local)
|
||||
{
|
||||
if (ctrl->scd_local->ctx)
|
||||
{
|
||||
/* We can't disconnect the primary context because libassuan
|
||||
does a waitpid on it and thus the system would hang.
|
||||
Instead we send a reset and keep that connection for
|
||||
reuse. */
|
||||
/* We send a reset and keep that connection for reuse. */
|
||||
if (ctrl->scd_local->ctx == primary_scd_ctx)
|
||||
{
|
||||
/* Send a RESTART to the SCD. This is required for the
|
||||
@ -604,6 +617,11 @@ agent_reset_scd (ctrl_t ctrl)
|
||||
ctrl->scd_local = NULL;
|
||||
}
|
||||
|
||||
err = npth_mutex_unlock (&start_scd_lock);
|
||||
if (err)
|
||||
log_error ("failed to release the start_scd lock: %s\n", strerror (err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user