From e62d57e799cc96370a5a5d75755c23a67b6907d7 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Wed, 31 Aug 2016 22:50:24 -0400 Subject: [PATCH] Reset signal_thread_key upon cancellation. Fixes pthread_exit() being called a second time during client cleanup when locking the connection list mutex. --- src/commands.c | 3 ++- src/common.h | 12 ------------ src/crypto.c | 1 + src/mutex.h | 11 +++++++++++ src/pwmd.c | 5 +++++ 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/commands.c b/src/commands.c index 0b5b6221..dc5cccf1 100644 --- a/src/commands.c +++ b/src/commands.c @@ -4150,8 +4150,9 @@ getinfo_command (assuan_context_t ctx, char *line) "ACL " #endif ""); + pthread_cleanup_push (xfree, buf); rc = xfer_data (ctx, buf, strlen (buf)); - xfree (buf); + pthread_cleanup_pop (1); } else if (!strcasecmp (line, "last_error")) { diff --git a/src/common.h b/src/common.h index e6fd45d3..e790690b 100644 --- a/src/common.h +++ b/src/common.h @@ -64,18 +64,6 @@ #define CLIENT_STATE_COMMAND 3 #define CLIENT_STATE_DISCON 4 -#ifndef HAVE_PTHREAD_CANCEL -pthread_key_t signal_thread_key; -#define TEST_CANCEL() do { \ - int *cancel = (int *) pthread_getspecific (signal_thread_key); \ - if (cancel && *cancel) \ - pthread_exit (NULL); \ - } while (0) -#else -#define TEST_CANCEL() -#endif - - struct client_thread_s { pthread_t tid; diff --git a/src/crypto.c b/src/crypto.c index d1aa60c3..8f844d7f 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -41,6 +41,7 @@ #include "mem.h" #include "util-string.h" #include "rcfile.h" +#include "mutex.h" static int keepalive; diff --git a/src/mutex.h b/src/mutex.h index c3f65f88..3b09d0fe 100644 --- a/src/mutex.h +++ b/src/mutex.h @@ -53,6 +53,17 @@ #include #include "rcfile.h" +#ifndef HAVE_PTHREAD_CANCEL +pthread_key_t signal_thread_key; +#define TEST_CANCEL() do { \ + int *cancel = (int *) pthread_getspecific (signal_thread_key); \ + if (cancel && *cancel) \ + pthread_exit (NULL); \ + } while (0) +#else +#define TEST_CANCEL() +#endif + #define INIT_TIMESPEC(t, ts) do { \ long s = (t*100000000)/1000000000; \ long l = (t*100000000)%1000000000; \ diff --git a/src/pwmd.c b/src/pwmd.c index c2437da5..dfa7c2ab 100644 --- a/src/pwmd.c +++ b/src/pwmd.c @@ -942,7 +942,12 @@ free_client_cb (void *arg) { struct client_thread_s *cn = arg; struct client_s *cl = cn->cl; +#ifndef HAVE_PTHREAD_CANCEL + char *tmp = pthread_getspecific (signal_thread_key); + xfree (tmp); + pthread_setspecific (signal_thread_key, NULL); +#endif MUTEX_LOCK (&cn_mutex); cn_thread_list = slist_remove (cn_thread_list, cn); MUTEX_UNLOCK (&cn_mutex); -- 2.11.4.GIT