diff --git a/modules/juce_core/native/juce_curl_Network.cpp b/modules/juce_core/native/juce_curl_Network.cpp index fb717a3da5..490d6448e9 100644 --- a/modules/juce_core/native/juce_curl_Network.cpp +++ b/modules/juce_core/native/juce_curl_Network.cpp @@ -46,6 +46,7 @@ struct CURLSymbols std::unique_ptr symbols (new CURLSymbols); #if JUCE_LOAD_CURL_SYMBOLS_LAZILY + const ScopedLock sl (getLibcurlLock()); #define JUCE_INIT_CURL_SYMBOL(name) if (! symbols->loadSymbol (symbols->name, #name)) return nullptr; #else #define JUCE_INIT_CURL_SYMBOL(name) symbols->name = ::name; @@ -70,6 +71,14 @@ struct CURLSymbols return symbols; } + // liburl's curl_multi_init calls curl_global_init which is not thread safe + // so we need to get a lock during calls to curl_multi_init and curl_multi_cleanup + static CriticalSection& getLibcurlLock() noexcept + { + static CriticalSection cs; + return cs; + } + private: CURLSymbols() = default; @@ -105,7 +114,10 @@ public: { jassert (symbols); // Unable to load libcurl! - multi = symbols->curl_multi_init(); + { + const ScopedLock sl (CURLSymbols::getLibcurlLock()); + multi = symbols->curl_multi_init(); + } if (multi != nullptr) { @@ -175,6 +187,7 @@ public: void cleanup() { const ScopedLock lock (cleanupLock); + const ScopedLock sl (CURLSymbols::getLibcurlLock()); if (curl != nullptr) {