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:
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));
}