From 90286cb1227ff973fbae2b60b1c3f3fc06e29686 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Mon, 29 Aug 2016 21:12:58 -0400 Subject: [PATCH] More cancellation fixes. --- src/pwmd.c | 42 ++++++++++++++++-------------------------- src/status.c | 44 ++++++++++++++++++++++++-------------------- src/tls.c | 10 ++++++---- 3 files changed, 46 insertions(+), 50 deletions(-) diff --git a/src/pwmd.c b/src/pwmd.c index 9add8b71..b5548397 100644 --- a/src/pwmd.c +++ b/src/pwmd.c @@ -129,6 +129,14 @@ static int signal_loop (sigset_t sigset); act.sa_sigaction = cb; \ sigaction (s, &act, NULL); \ } while (0) + +#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 #ifndef HAVE_PTHREAD_CANCEL @@ -210,12 +218,7 @@ reload_rcfile_thread (void *arg) pthread_cleanup_push (release_mutex_cb, &rcfile_mutex); pthread_cond_wait (&rcfile_cond, &rcfile_mutex); -#ifndef HAVE_PTHREAD_CANCEL - int *cancel = (int *) pthread_getspecific (signal_thread_key); - if (*cancel) - pthread_exit (NULL); -#endif - + TEST_CANCEL (); keep = config_keep_save (); log_write (_("reloading configuration file '%s'"), rcfile); @@ -759,8 +762,9 @@ validate_peer (struct client_s *cl) #endif MUTEX_LOCK (&cn_mutex); + pthread_cleanup_push (release_mutex_cb, &cn_mutex); rc = do_validate_peer (cl->ctx, "global", &cl->thd->peer); - MUTEX_UNLOCK (&cn_mutex); + pthread_cleanup_pop (1); log_write ("peer %s: uid=%i, gid=%i, pid=%i, rc=%u", !rc ? _("accepted") : _("rejected"), cl->thd->peer->uid, cl->thd->peer->gid, cl->thd->peer->pid, rc); @@ -1033,6 +1037,7 @@ free_all_clients (int atfork) } MUTEX_LOCK (&cn_mutex); + pthread_cleanup_push (release_mutex_cb, &cn_mutex); while (slist_length (cn_thread_list)) { @@ -1043,7 +1048,7 @@ free_all_clients (int atfork) } exiting = 1; - MUTEX_UNLOCK (&cn_mutex); + pthread_cleanup_pop (1); cache_deinit (atfork); } @@ -1789,13 +1794,8 @@ accept_thread (void *arg) struct sockaddr_un raddr; int fd, s = 0; struct pollfd fds[3]; -#ifndef HAVE_PTHREAD_CANCEL - int *sigusr2 = (int *) pthread_getspecific (signal_thread_key); - - if (*sigusr2) - break; -#endif + TEST_CANCEL (); memset (fds, 0, sizeof (fds)); fds[s].fd = sockfd; fds[s++].events = POLLIN; @@ -1889,14 +1889,8 @@ cache_timer_thread (void *arg) { struct timeval tv = { 1, 0 }; unsigned keepalive = config_get_integer ("global", "keepalive_interval"); -#ifndef HAVE_PTHREAD_CANCEL - int *n; - - n = (int *) pthread_getspecific (signal_thread_key); - if (*n) - break; -#endif + TEST_CANCEL (); select (0, NULL, NULL, NULL, &tv); cache_adjust_timeout (); @@ -1990,11 +1984,7 @@ waiting_for_exit (void *arg) if (!n) break; -#ifndef HAVE_PTHREAD_CANCEL - int *s = (int *) pthread_getspecific (signal_thread_key); - if (*s) - break; -#endif + TEST_CANCEL (); if (last != n) { diff --git a/src/status.c b/src/status.c index c2748f84..30a2abd7 100644 --- a/src/status.c +++ b/src/status.c @@ -225,6 +225,8 @@ do_send_status_all (status_msg_t s, const char *line, pthread_t *not_tid, int i = 0; int t = slist_length (cn_thread_list); + pthread_cleanup_push (release_mutex_cb, &cn_mutex); + for (; i < t; i++) { struct client_thread_s *thd = slist_nth_data (cn_thread_list, i); @@ -243,6 +245,7 @@ do_send_status_all (status_msg_t s, const char *line, pthread_t *not_tid, continue; MUTEX_LOCK (&thd->status_mutex); + pthread_cleanup_push (release_mutex_cb, &thd->status_mutex); for (p = thd->msg_queue; p; p = p->next) { @@ -269,35 +272,36 @@ do_send_status_all (status_msg_t s, const char *line, pthread_t *not_tid, } thd->wrote_status = 1; - MUTEX_UNLOCK (&thd->status_mutex); - continue; } + else + { + msg = xcalloc (1, sizeof (struct status_msg_s)); + msg->s = s; + msg->line = line ? str_dup (line) : NULL; - msg = xcalloc (1, sizeof (struct status_msg_s)); - msg->s = s; - msg->line = line ? str_dup (line) : NULL; + for (p = thd->msg_queue; p && p->next; p = p->next); + if (!p) + thd->msg_queue = msg; + else + p->next = msg; - for (p = thd->msg_queue; p && p->next; p = p->next); - if (!p) - thd->msg_queue = msg; - else - p->next = msg; + if (!thd->wrote_status) + { + ssize_t ret = write (thd->status_msg_pipe[1], &c, 1); - if (!thd->wrote_status) - { - ssize_t ret = write (thd->status_msg_pipe[1], &c, 1); + rc = gpg_error_from_syserror (); + if (ret == -1) + log_write ("%s (%i): %s", __FUNCTION__, __LINE__, + pwmd_strerror (rc)); + } - rc = gpg_error_from_syserror (); - if (ret == -1) - log_write ("%s (%i): %s", __FUNCTION__, __LINE__, - pwmd_strerror (rc)); + thd->wrote_status = 1; } - thd->wrote_status = 1; - MUTEX_UNLOCK (&thd->status_mutex); + pthread_cleanup_pop (1); } - MUTEX_UNLOCK (&cn_mutex); + pthread_cleanup_pop (1); } void diff --git a/src/tls.c b/src/tls.c index 5c0c8f4a..a83f7074 100644 --- a/src/tls.c +++ b/src/tls.c @@ -329,6 +329,7 @@ tls_init_params () return 0; MUTEX_LOCK(&tls_mutex); + pthread_cleanup_push (release_mutex_cb, &tls_mutex); tls_deinit_params (); n = gnutls_certificate_allocate_credentials (&x509_cred); if (n != GNUTLS_E_SUCCESS) @@ -424,12 +425,13 @@ tls_init_params () xfree (tmp); } - MUTEX_UNLOCK(&tls_mutex); - return 0; + rc = 0; fail: - tls_deinit_params (); - MUTEX_UNLOCK(&tls_mutex); + if (rc) + tls_deinit_params (); + + pthread_cleanup_pop (1); return rc; } -- 2.11.4.GIT