aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2020-03-17 05:00:31 +0000
committerNIIBE Yutaka <[email protected]>2020-04-02 05:11:52 +0000
commit213d36cead9d4b94a406af47c7749355c0d3a3f2 (patch)
tree9123349f601ed1f8b6ab51cc9be9cb36c7feb4b4
parentnpth_sigwait is not available. (diff)
downloadgnupg-213d36cead9d4b94a406af47c7749355c0d3a3f2.tar.gz
gnupg-213d36cead9d4b94a406af47c7749355c0d3a3f2.zip
watch: use condition variable.
Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r--scd/app.c31
-rw-r--r--scd/command.c40
-rw-r--r--scd/scdaemon.c3
-rw-r--r--scd/scdaemon.h2
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 (&notify_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 (&notify_cond);
+}
+
+int
+app_wait (void)
+{
+ int ret;
+
+ npth_mutex_lock (&card_list_lock);
+ npth_cond_wait (&notify_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*/