asyn-thrdd: remove condition variable

Add a flag `thrd_don` to assess if the resolving thread has finished and
only destroy the context when *both* ref_count reaches 0 and thrd_done
is true.

Closes #18345
This commit is contained in:
Stefan Eissing 2025-08-21 21:50:20 +02:00 committed by Daniel Stenberg
parent c83fa990bd
commit 8ebea37eb1
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 13 additions and 42 deletions

View File

@ -128,9 +128,12 @@ static void addr_ctx_unlink(struct async_thrdd_addr_ctx **paddr_ctx,
return;
Curl_mutex_acquire(&addr_ctx->mutx);
if(!data) /* called by resolving thread */
addr_ctx->thrd_done = TRUE;
DEBUGASSERT(addr_ctx->ref_count);
--addr_ctx->ref_count;
destroy = !addr_ctx->ref_count; /* was the last one */
destroy = (!addr_ctx->ref_count && addr_ctx->thrd_done);
#ifndef CURL_DISABLE_SOCKETPAIR
if(!destroy) {
@ -168,9 +171,6 @@ static void addr_ctx_unlink(struct async_thrdd_addr_ctx **paddr_ctx,
Curl_mutex_release(&addr_ctx->mutx);
if(destroy) {
#ifdef USE_CURL_COND_T
Curl_cond_destroy(&addr_ctx->cond);
#endif
Curl_mutex_destroy(&addr_ctx->mutx);
free(addr_ctx->hostname);
if(addr_ctx->res)
@ -206,9 +206,6 @@ addr_ctx_create(struct Curl_easy *data,
#endif
Curl_mutex_init(&addr_ctx->mutx);
#ifdef USE_CURL_COND_T
Curl_cond_init(&addr_ctx->cond);
#endif
#ifndef CURL_DISABLE_SOCKETPAIR
/* create socket pair or pipe */
@ -245,13 +242,8 @@ static bool asyn_thrd_start(struct async_thrdd_addr_ctx *addr_ctx)
{
Curl_thread_disable_cancel();
Curl_mutex_acquire(&addr_ctx->mutx);
DEBUGASSERT(addr_ctx->ref_count);
++addr_ctx->ref_count;
#ifdef USE_CURL_COND_T
Curl_cond_signal(&addr_ctx->cond);
#endif
Curl_mutex_release(&addr_ctx->mutx);
return TRUE;
}
@ -376,10 +368,10 @@ static void async_thrdd_destroy(struct Curl_easy *data)
#endif
if(thrdd->addr && (thrdd->addr->thread_hnd != curl_thread_t_null)) {
bool done = TRUE;
bool done;
Curl_mutex_acquire(&addr->mutx);
done = (addr->ref_count <= 1);
done = addr->thrd_done;
Curl_mutex_release(&addr->mutx);
if(done) {
Curl_thread_join(&addr->thread_hnd);
@ -498,18 +490,12 @@ static bool async_thrdd_init(struct Curl_easy *data,
if(addr_ctx->thread_hnd == curl_thread_t_null) {
/* The thread never started */
addr_ctx->thrd_done = TRUE;
Curl_mutex_release(&addr_ctx->mutx);
err = errno;
goto err_exit;
}
else {
#ifdef USE_CURL_COND_T
/* need to handshake with thread for participation in ref counting */
Curl_cond_wait(&addr_ctx->cond, &addr_ctx->mutx);
DEBUGASSERT(addr_ctx->ref_count >= 1);
#endif
Curl_mutex_release(&addr_ctx->mutx);
}
Curl_mutex_release(&addr_ctx->mutx);
#ifdef USE_HTTPSRR_ARES
if(async_rr_start(data))
@ -537,7 +523,7 @@ static void async_thrdd_shutdown(struct Curl_easy *data)
return;
Curl_mutex_acquire(&addr_ctx->mutx);
done = (addr_ctx->ref_count <= 1);
done = addr_ctx->thrd_done;
/* We are no longer interested in wakeups */
if(addr_ctx->sock_pair[1] != CURL_SOCKET_BAD) {
wakeup_close(addr_ctx->sock_pair[1]);
@ -571,6 +557,7 @@ static CURLcode asyn_thrdd_await(struct Curl_easy *data,
#ifdef DEBUGBUILD
Curl_mutex_acquire(&addr_ctx->mutx);
DEBUGASSERT(addr_ctx->ref_count == 1);
DEBUGASSERT(addr_ctx->thrd_done);
Curl_mutex_release(&addr_ctx->mutx);
#endif
if(entry)
@ -660,7 +647,7 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
return CURLE_FAILED_INIT;
Curl_mutex_acquire(&thrdd->addr->mutx);
done = (thrdd->addr->ref_count == 1);
done = thrdd->addr->thrd_done;
Curl_mutex_release(&thrdd->addr->mutx);
if(done) {

View File

@ -180,9 +180,6 @@ struct async_thrdd_addr_ctx {
char *hostname; /* hostname to resolve, Curl_async.hostname
duplicate */
curl_mutex_t mutx;
#ifdef USE_CURL_COND_T
curl_cond_t cond;
#endif
#ifndef CURL_DISABLE_SOCKETPAIR
curl_socket_t sock_pair[2]; /* eventfd/pipes/socket pair */
#endif
@ -196,6 +193,7 @@ struct async_thrdd_addr_ctx {
int port;
int sock_error;
int ref_count;
BIT(thrd_done);
};
/* Context for threaded resolver */

View File

@ -36,7 +36,7 @@
#include "curl_threads.h"
#include "curl_memory.h"
/* The last #include file should be: */
/* The last #include FILE should be: */
#include "memdebug.h"
#ifdef USE_THREADS_POSIX

View File

@ -34,12 +34,6 @@
# define Curl_mutex_acquire(m) pthread_mutex_lock(m)
# define Curl_mutex_release(m) pthread_mutex_unlock(m)
# define Curl_mutex_destroy(m) pthread_mutex_destroy(m)
# define USE_CURL_COND_T
# define curl_cond_t pthread_cond_t
# define Curl_cond_init(c) pthread_cond_init(c, NULL)
# define Curl_cond_destroy(c) pthread_cond_destroy(c)
# define Curl_cond_wait(c, m) pthread_cond_wait(c, m)
# define Curl_cond_signal(c) pthread_cond_signal(c)
#elif defined(USE_THREADS_WIN32)
# define CURL_STDCALL __stdcall
# define curl_mutex_t CRITICAL_SECTION
@ -53,14 +47,6 @@
# define Curl_mutex_acquire(m) EnterCriticalSection(m)
# define Curl_mutex_release(m) LeaveCriticalSection(m)
# define Curl_mutex_destroy(m) DeleteCriticalSection(m)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
# define USE_CURL_COND_T
# define curl_cond_t CONDITION_VARIABLE
# define Curl_cond_init(c) InitializeConditionVariable(c)
# define Curl_cond_destroy(c) (void)(c)
# define Curl_cond_wait(c, m) SleepConditionVariableCS(c, m, INFINITE)
# define Curl_cond_signal(c) WakeConditionVariable(c)
# endif
#else
# define CURL_STDCALL
#endif