mirror of
https://github.com/curl/curl.git
synced 2026-04-14 22:41:40 +03:00
asyn-thrdd: use condition var more carefully
When the thread started is too fast, the signal will come before the wait. Add an additional check before the wait to catch the thread having started or already ended. Closes #18344
This commit is contained in:
parent
b6a5f67259
commit
bd4622bfaf
2 changed files with 18 additions and 6 deletions
|
|
@ -135,6 +135,13 @@ static void addr_ctx_unlink(struct async_thrdd_addr_ctx **paddr_ctx,
|
|||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
if(!destroy) {
|
||||
if(!data) { /* Called from thread, transfer still waiting on results. */
|
||||
/* Mark thread as done and signal the condition again, in case the
|
||||
* one waiting missed our fist signal at the start. */
|
||||
addr_ctx->thrd_done = TRUE;
|
||||
#ifdef USE_CURL_COND_T
|
||||
Curl_cond_signal(&addr_ctx->cond);
|
||||
#endif
|
||||
|
||||
if(addr_ctx->sock_pair[1] != CURL_SOCKET_BAD) {
|
||||
#ifdef USE_EVENTFD
|
||||
const uint64_t buf[1] = { 1 };
|
||||
|
|
@ -379,7 +386,7 @@ static void async_thrdd_destroy(struct Curl_easy *data)
|
|||
bool done = TRUE;
|
||||
|
||||
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);
|
||||
|
|
@ -504,9 +511,13 @@ static bool async_thrdd_init(struct Curl_easy *data,
|
|||
}
|
||||
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);
|
||||
/* need to handshake with thread for participation in ref counting.
|
||||
* We wait to see the thread having incremented `ref_count`, so it
|
||||
* started. However it may run to its end before we get the
|
||||
* signal, in which case `ref_count` is 1 again, but then
|
||||
* `thrd_done` is TRUE.*/
|
||||
while((addr_ctx->ref_count <= 1) && !addr_ctx->thrd_done)
|
||||
Curl_cond_wait(&addr_ctx->cond, &addr_ctx->mutx);
|
||||
#endif
|
||||
Curl_mutex_release(&addr_ctx->mutx);
|
||||
}
|
||||
|
|
@ -537,7 +548,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]);
|
||||
|
|
@ -660,7 +671,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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue