From 213d36cead9d4b94a406af47c7749355c0d3a3f2 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 17 Mar 2020 14:00:31 +0900 Subject: [PATCH] watch: use condition variable. Signed-off-by: NIIBE Yutaka --- scd/app.c | 31 +++++++++++++++++++++++++++++++ scd/command.c | 40 ++++++++++++++++++++-------------------- scd/scdaemon.c | 3 +++ scd/scdaemon.h | 2 ++ 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/scd/app.c b/scd/app.c index 7193d0ba7..da70f8705 100644 --- a/scd/app.c +++ b/scd/app.c @@ -42,6 +42,9 @@ send_serialno_and_app_status (card_t card, int with_apps, ctrl_t ctrl); * applications. */ static npth_mutex_t card_list_lock; +/* Notification to threads which keep watching the status change. */ +static npth_cond_t notify_cond; + /* A list of card contexts. A card is a collection of applications * (described by app_t) on the same physical token. */ static card_t card_top; @@ -2013,10 +2016,19 @@ initialize_module_command (void) return err; } + err = npth_cond_init (¬ify_cond, NULL); + if (err) + { + err = gpg_error_from_syserror (); + log_error ("npth_cond_init failed: %s\n", gpg_strerror (err)); + return; + } + return apdu_init (); } + /* Sort helper for app_send_card_list. */ static int compare_card_list_items (const void *arg_a, const void *arg_b) @@ -2279,3 +2291,22 @@ app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str, npth_mutex_unlock (&card_list_lock); return c; } + +void +app_notify (void) +{ + npth_cond_broadcast (¬ify_cond); +} + +int +app_wait (void) +{ + int ret; + + npth_mutex_lock (&card_list_lock); + npth_cond_wait (¬ify_cond, &card_list_lock); + ret = (card_top == NULL); + npth_mutex_unlock (&card_list_lock); + + return ret; +} diff --git a/scd/command.c b/scd/command.c index 1c88b384d..f611c1ea6 100644 --- a/scd/command.c +++ b/scd/command.c @@ -2158,35 +2158,35 @@ cmd_list_device (assuan_context_t ctx, char *line) int watch = 0; if (has_option (line, "--watch")) - watch = 1; + { + watch = 1; + ctrl->server_local->watching_status = 1; + } + /* Clear the remove flag so that the open_card is able to reread it. */ + if (ctrl->server_local->card_removed) + ctrl->server_local->card_removed = 0; + + /* Then, actively try to open device(s) available. */ if ((err = open_card (ctrl))) return err; + /* Remove reference(s) to the card. */ + ctrl->card_ctx = NULL; + ctrl->current_apptype = APPTYPE_NONE; + card_unref (ctrl->card_ctx); + if (watch) - { - ctrl->server_local->watching_status = 1; - while (1) + while (1) + if (app_wait ()) { - int sig; - - npth_unprotect (); - sigwait (npth_sigev_sigmask (), &sig); - npth_protect (); - - assuan_write_status (ctx, "signal", ""); - - if (ctrl->server_local->card_removed) - { - ctrl->server_local->watching_status = 0; - return 0; - } + ctrl->server_local->watching_status = 0; + return 0; } - } + else + assuan_write_status (ctx, "app_wait", "... returns"); - /* XXX: Actively try to open devices available. */ return gpg_error (GPG_ERR_NOT_FOUND); - return 0; } /* Return true if the command CMD implements the option OPT. */ diff --git a/scd/scdaemon.c b/scd/scdaemon.c index b7bbc0361..1f34809bc 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1220,6 +1220,9 @@ scd_kick_the_loop (void) log_error ("SetEvent for scd_kick_the_loop failed: %s\n", gpg_strerror (gpg_error_from_syserror ())); #endif + + /* Also, notify watching threads. */ + app_notify (); } /* Connection handler loop. Wait for connection requests and spawn a diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 391f16578..c79c272a0 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -153,5 +153,7 @@ int get_active_connection_count (void); /*-- app.c --*/ int scd_update_reader_status_file (void); +int app_wait (void); +void app_notify (void); #endif /*SCDAEMON_H*/