exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit a47090924e84c7435736cdeab7724580f5c68748
parent 9a68b1c633019dfe2c2072315be06570a105be52
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Mon, 12 May 2025 14:42:46 +0200

fix unclean pthread destruction (fixes #9944)

Diffstat:
Msrc/util/secmod_common.c | 70+++++++++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 43 insertions(+), 27 deletions(-)

diff --git a/src/util/secmod_common.c b/src/util/secmod_common.c @@ -365,26 +365,6 @@ TES_await_ready (struct TES_Client *client) } -void -TES_free_client (struct TES_Client *client) -{ - GNUNET_assert (0 == pthread_mutex_lock (&TES_clients_lock)); - GNUNET_CONTAINER_DLL_remove (TES_clients_head, - TES_clients_tail, - client); - GNUNET_assert (0 == pthread_mutex_unlock (&TES_clients_lock)); - GNUNET_break (0 == close (client->csock)); -#ifdef __linux__ - GNUNET_break (0 == close (client->esock)); -#else - GNUNET_break (0 == close (client->esock_in)); - GNUNET_break (0 == close (client->esock_out)); -#endif - pthread_detach (client->worker); - GNUNET_free (client); -} - - /** * Main function of a worker thread that signs. * @@ -400,7 +380,6 @@ sign_worker (void *cls) client->cb.init (client)) { GNUNET_break (0); - TES_free_client (client); return NULL; } while (! in_shutdown) @@ -411,12 +390,14 @@ sign_worker (void *cls) client->cb.updater (client)) break; } - if (GNUNET_SYSERR == - TES_read_work (client, - client->cb.dispatch)) - break; + else + { + if (GNUNET_SYSERR == + TES_read_work (client, + client->cb.dispatch)) + break; + } } - TES_free_client (client); return NULL; } @@ -496,7 +477,19 @@ listen_job (void *cls) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "pthread_create"); - TES_free_client (client); + GNUNET_assert (0 == pthread_mutex_lock (&TES_clients_lock)); + GNUNET_CONTAINER_DLL_remove (TES_clients_head, + TES_clients_tail, + client); + GNUNET_assert (0 == pthread_mutex_unlock (&TES_clients_lock)); + GNUNET_break (0 == close (client->csock)); +#ifdef __linux__ + GNUNET_break (0 == close (client->esock)); +#else + GNUNET_break (0 == close (client->esock_in)); + GNUNET_break (0 == close (client->esock_out)); +#endif + GNUNET_free (client); } } } @@ -570,6 +563,8 @@ TES_listen_start (const struct GNUNET_CONFIGURATION_Handle *cfg, void TES_listen_stop (void) { + struct TES_Client *client; + if (NULL != listen_task) { GNUNET_SCHEDULER_cancel (listen_task); @@ -590,4 +585,25 @@ TES_listen_stop (void) GNUNET_free (unixpath); in_shutdown = true; TES_wake_clients (); + GNUNET_assert (0 == pthread_mutex_lock (&TES_clients_lock)); + while (NULL != (client = TES_clients_head)) + { + void *rval; + + GNUNET_CONTAINER_DLL_remove (TES_clients_head, + TES_clients_tail, + client); + GNUNET_break (0 == + pthread_join (client->worker, + &rval)); + GNUNET_break (0 == close (client->csock)); +#ifdef __linux__ + GNUNET_break (0 == close (client->esock)); +#else + GNUNET_break (0 == close (client->esock_in)); + GNUNET_break (0 == close (client->esock_out)); +#endif + GNUNET_free (client); + } + GNUNET_assert (0 == pthread_mutex_unlock (&TES_clients_lock)); }