aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2018-11-28 05:59:44 +0000
committerNIIBE Yutaka <[email protected]>2018-11-28 05:59:44 +0000
commit47106ac435e891ced67f0ad9bb6b2ee12098c880 (patch)
treeba103456127440c583b48b13efbf24997311c8ab
parentagent: Better serialization for scdaemon access. (diff)
downloadgnupg-47106ac435e891ced67f0ad9bb6b2ee12098c880.tar.gz
gnupg-47106ac435e891ced67f0ad9bb6b2ee12098c880.zip
scd: Serialize opening device by select_application.
* scd/app.c (app_new_register): Don't lock APP_LIST_LOCK here. (select_application): Lock with APP_LIST_LOCK earlier. -- What we want to do here is to serialize the call of select_application. In the old code, it was possible that a call of select_application was blocked internally, and then another call of select_application entered. We can have a dedicated lock for call of select_application, but it is easier to re-use APP_LIST_LOCK. Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r--scd/app.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/scd/app.c b/scd/app.c
index a82db26cd..d16300efa 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -299,11 +299,8 @@ app_new_register (int slot, ctrl_t ctrl, const char *name,
}
app->periodical_check_needed = periodical_check_needed;
-
- npth_mutex_lock (&app_list_lock);
app->next = app_top;
app_top = app;
- npth_mutex_unlock (&app_list_lock);
unlock_app (app);
return 0;
}
@@ -322,6 +319,8 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
*r_app = NULL;
+ npth_mutex_lock (&app_list_lock);
+
if (scan || !app_top)
{
struct dev_list *l;
@@ -330,7 +329,10 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
/* Scan the devices to find new device(s). */
err = apdu_dev_list_start (opt.reader_port, &l);
if (err)
- return err;
+ {
+ npth_mutex_unlock (&app_list_lock);
+ return err;
+ }
while (1)
{
@@ -365,7 +367,6 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
scd_kick_the_loop ();
}
- npth_mutex_lock (&app_list_lock);
for (a = app_top; a; a = a->next)
{
lock_app (a, ctrl);