diff --git a/vendor/curl-sys-0.4.91/curl/lib/creds.c b/vendor/curl-sys-0.4.91/curl/lib/creds.c index 5507ae86f6..d5f700b8ed 100644 --- a/vendor/curl-sys-0.4.91/curl/lib/creds.c +++ b/vendor/curl-sys-0.4.91/curl/lib/creds.c @@ -29,6 +29,7 @@ #include "curl_trc.h" #include "strcase.h" #include "urldata.h" +#include "moli_refcount.h" CURLcode Curl_creds_create(const char *user, @@ -132,10 +133,8 @@ void Curl_creds_link(struct Curl_creds **pdest, struct Curl_creds *src) if(*pdest != src) { Curl_creds_unlink(pdest); *pdest = src; - if(src) { - DEBUGASSERT(src->refcount < UINT32_MAX); - src->refcount++; - } + if(src) + moli_refcount_link(&src->refcount); } } @@ -144,11 +143,8 @@ void Curl_creds_unlink(struct Curl_creds **pcreds) if(*pcreds) { struct Curl_creds *creds = *pcreds; - DEBUGASSERT(creds->refcount); *pcreds = NULL; - if(creds->refcount) - creds->refcount--; - if(!creds->refcount) { + if(moli_refcount_unlink(&creds->refcount)) { curlx_memzero(creds, sizeof(*creds) + creds->bufsize); curlx_free(creds); } diff --git a/vendor/curl-sys-0.4.91/curl/lib/moli_refcount.h b/vendor/curl-sys-0.4.91/curl/lib/moli_refcount.h new file mode 100644 index 0000000000..258bec8978 --- /dev/null +++ b/vendor/curl-sys-0.4.91/curl/lib/moli_refcount.h @@ -0,0 +1,46 @@ +#ifndef HEADER_CURL_MOLI_REFCOUNT_H +#define HEADER_CURL_MOLI_REFCOUNT_H +/* SPDX-License-Identifier: curl */ + +#include "easy_lock.h" + +/* A removed easy may be cleaned up while its former multi reuses a cached + * connection. Both retain peers and credentials. Protect their counts even + * though the application never uses the same easy from two threads. + * + * Each including translation unit owns one object family and its lock. Only + * the count is protected; no allocation, destruction or curl callbacks run + * under the lock. Use curl's existing platform lock and single-thread fallback. + */ +#ifdef GLOBAL_INIT_IS_THREADSAFE +static curl_simple_lock moli_refcount_lock = CURL_SIMPLE_LOCK_INIT; +#endif + +static CURL_INLINE void moli_refcount_link(uint32_t *count) +{ +#ifdef GLOBAL_INIT_IS_THREADSAFE + curl_simple_lock_lock(&moli_refcount_lock); +#endif + DEBUGASSERT(*count && *count < UINT32_MAX); + ++*count; +#ifdef GLOBAL_INIT_IS_THREADSAFE + curl_simple_lock_unlock(&moli_refcount_lock); +#endif +} + +static CURL_INLINE bool moli_refcount_unlink(uint32_t *count) +{ + bool last; +#ifdef GLOBAL_INIT_IS_THREADSAFE + curl_simple_lock_lock(&moli_refcount_lock); +#endif + DEBUGASSERT(*count); + last = !--*count; +#ifdef GLOBAL_INIT_IS_THREADSAFE + curl_simple_lock_unlock(&moli_refcount_lock); +#endif + /* Do not read the count again: another owner may already have freed it. */ + return last; +} + +#endif /* HEADER_CURL_MOLI_REFCOUNT_H */ diff --git a/vendor/curl-sys-0.4.91/curl/lib/peer.c b/vendor/curl-sys-0.4.91/curl/lib/peer.c index b5bf7b7334..9e588ffb02 100644 --- a/vendor/curl-sys-0.4.91/curl/lib/peer.c +++ b/vendor/curl-sys-0.4.91/curl/lib/peer.c @@ -76,6 +76,7 @@ #include "url.h" #include "urlapi-int.h" #include "vtls/vtls.h" +#include "moli_refcount.h" struct peer_parse { const struct Curl_scheme *scheme; @@ -296,10 +297,8 @@ void Curl_peer_link(struct Curl_peer **pdest, struct Curl_peer *src) if(*pdest != src) { Curl_peer_unlink(pdest); *pdest = src; - if(src) { - DEBUGASSERT(src->refcount < UINT32_MAX); - src->refcount++; - } + if(src) + moli_refcount_link(&src->refcount); } } @@ -308,11 +307,8 @@ void Curl_peer_unlink(struct Curl_peer **ppeer) if(*ppeer) { struct Curl_peer *peer = *ppeer; - DEBUGASSERT(peer->refcount); *ppeer = NULL; - if(peer->refcount) - peer->refcount--; - if(!peer->refcount) { + if(moli_refcount_unlink(&peer->refcount)) { curlx_free(peer); } }