From 9900db8c8b9cd9e0c839420db8ff07642fa305a4 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Sun, 2 Mar 2008 10:44:37 -0500 Subject: [PATCH] Use an event in lock_file_mutex() to test if the client is still connected. Fixes terminating the client thread that was waiting for the lock but disconnected unexpectedly. --- src/commands.c | 37 ++++++++++++++++++++++++++++++++++--- src/pinentry.c | 2 +- src/pwmd.c | 9 ++++++++- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/commands.c b/src/commands.c index aea6223e..9283927f 100644 --- a/src/commands.c +++ b/src/commands.c @@ -147,6 +147,19 @@ void unlock_file_mutex(struct client_s *client) client->has_lock = client->is_lock_cmd = FALSE; } +static int lock_mutex_cb(void *arg) +{ + struct client_s *client = arg; + gpg_error_t rc; + + rc = send_status(client->ctx, STATUS_LOCKED); + + if (rc) + log_write("%s", gpg_strerror(rc)); + + return rc ? TRUE : FALSE; +} + gpg_error_t lock_file_mutex(struct client_s *client) { pth_mutex_t *m; @@ -165,10 +178,28 @@ gpg_error_t lock_file_mutex(struct client_s *client) if (pth_mutex_acquire(m, TRUE, NULL) == FALSE) { if (errno == EBUSY) { - if (client->ctx) - assuan_write_status(client->ctx, "LOCKED", N_("Waiting for lock")); + if (client->ctx) { + pth_event_t ev; + send_status(client->ctx, STATUS_LOCKED); + + /* + * If a client disconnects unexpectedly while waiting for a lock, + * this lets the thread terminate because send_status() will + * return an error. + */ + ev = pth_event(PTH_EVENT_FUNC, lock_mutex_cb, client, + pth_time(0, 100000)); + pth_mutex_acquire(m, FALSE, ev); + + if (pth_event_occurred(ev)) { + pth_event_free(ev, PTH_FREE_THIS); + return GPG_ERR_EOF; + } - pth_mutex_acquire(m, FALSE, NULL); + pth_event_free(ev, PTH_FREE_THIS); + } + else + pth_mutex_acquire(m, FALSE, NULL); } else { gint e = errno; diff --git a/src/pinentry.c b/src/pinentry.c index c0733b6d..de8c6cd9 100644 --- a/src/pinentry.c +++ b/src/pinentry.c @@ -372,7 +372,7 @@ void lock_pin_mutex(struct client_s *client) { if (pth_mutex_acquire(&pin_mutex, TRUE, NULL) == FALSE) { if (client->ctx) - assuan_write_status(client->ctx, "LOCKED", N_("Waiting for lock")); + send_status(client->ctx, STATUS_LOCKED); pth_mutex_acquire(&pin_mutex, FALSE, NULL); } diff --git a/src/pwmd.c b/src/pwmd.c index 4ccc85e0..4ecd4b34 100644 --- a/src/pwmd.c +++ b/src/pwmd.c @@ -166,7 +166,10 @@ void log_write(const gchar *fmt, ...) } attr = pth_attr_of(pth_self()); - pth_attr_get(attr, PTH_ATTR_NAME, &name); + + if (pth_attr_get(attr, PTH_ATTR_NAME, &name) == FALSE) + name = "unknown"; + pth_attr_destroy(attr); if (log_syslog == TRUE) @@ -305,6 +308,10 @@ gpg_error_t send_status(assuan_context_t ctx, status_msg_t which) case STATUS_KEEPALIVE: status = "KEEPALIVE"; break; + case STATUS_LOCKED: + status = "LOCKED"; + line = N_("Waiting for lock"); + break; } return assuan_write_status(ctx, status, line); -- 2.11.4.GIT