diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2020-11-30 18:16:48 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-12-07 23:08:35 +0000 |
commit | 75d11df6d2cb301a6e201282b1fc4629621cce72 (patch) | |
tree | c063d3a2e6b4cd729e1fdabd68b54fa538201ff5 | |
parent | 5b31ee18c899e02e08fed6fbffd9cff7833603f0 (diff) | |
download | mongo-75d11df6d2cb301a6e201282b1fc4629621cce72.tar.gz |
SERVER-51858 Fix curl locking
(cherry picked from commit 267d28ce067bb213cff816c55bac0b5c1527d500)
-rw-r--r-- | src/mongo/util/net/http_client_curl.cpp | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/src/mongo/util/net/http_client_curl.cpp b/src/mongo/util/net/http_client_curl.cpp index ca8263595d9..07d4e5886d8 100644 --- a/src/mongo/util/net/http_client_curl.cpp +++ b/src/mongo/util/net/http_client_curl.cpp @@ -120,29 +120,64 @@ private: curl_share_setopt(_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); curl_share_setopt(_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); curl_share_setopt(_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); - curl_share_setopt(_share, CURLSHOPT_USERDATA, &this->_shareMutex); + curl_share_setopt(_share, CURLSHOPT_USERDATA, this); curl_share_setopt(_share, CURLSHOPT_LOCKFUNC, _lockShare); curl_share_setopt(_share, CURLSHOPT_UNLOCKFUNC, _unlockShare); return Status::OK(); } - static void _lockShare(CURL*, curl_lock_data, curl_lock_access, void* ctx) { - reinterpret_cast<stdx::recursive_mutex*>(ctx)->lock(); + static void _lockShare(CURL*, curl_lock_data lock_data, curl_lock_access, void* ctx) { + // curl_lock_access maps to shared and single access, i.e. a read and exclusive lock + // except the unlock method does not have curl_lock_access as a parameter so we map + // all lock requests to regular mutexes + switch (lock_data) { + case CURL_LOCK_DATA_SHARE: + reinterpret_cast<CurlLibraryManager*>(ctx)->_mutexShare.lock(); + break; + case CURL_LOCK_DATA_DNS: + reinterpret_cast<CurlLibraryManager*>(ctx)->_mutexDns.lock(); + break; + case CURL_LOCK_DATA_SSL_SESSION: + reinterpret_cast<CurlLibraryManager*>(ctx)->_mutexSSLSession.lock(); + break; + case CURL_LOCK_DATA_CONNECT: + reinterpret_cast<CurlLibraryManager*>(ctx)->_mutexConnect.lock(); + break; + default: + fassert(5185801, "Unsupported curl lock type"); + } } - static void _unlockShare(CURL*, curl_lock_data, void* ctx) { - reinterpret_cast<stdx::recursive_mutex*>(ctx)->unlock(); + + static void _unlockShare(CURL*, curl_lock_data lock_data, void* ctx) { + switch (lock_data) { + case CURL_LOCK_DATA_SHARE: + reinterpret_cast<CurlLibraryManager*>(ctx)->_mutexShare.unlock(); + break; + case CURL_LOCK_DATA_DNS: + reinterpret_cast<CurlLibraryManager*>(ctx)->_mutexDns.unlock(); + break; + case CURL_LOCK_DATA_SSL_SESSION: + reinterpret_cast<CurlLibraryManager*>(ctx)->_mutexSSLSession.unlock(); + break; + case CURL_LOCK_DATA_CONNECT: + reinterpret_cast<CurlLibraryManager*>(ctx)->_mutexConnect.unlock(); + break; + default: + fassert(5185802, "Unsupported curl unlock type"); + } } private: bool _initialized = false; CURLSH* _share = nullptr; - // A recursive mutex here is needed because CURL needs to lock this multiple times depending - // on the "internal CURL type" of the object that CURL is sending. Using a normal mutex - // causes the CURL system to deadlock. - stdx::recursive_mutex _shareMutex{}; + Mutex _mutexDns = MONGO_MAKE_LATCH("CurlLibraryManager::ShareDns"); + Mutex _mutexConnect = MONGO_MAKE_LATCH("CurlLibraryManager::ShareConnect"); + Mutex _mutexSSLSession = MONGO_MAKE_LATCH("CurlLibraryManager::ShareSSLSession"); + Mutex _mutexShare = MONGO_MAKE_LATCH("CurlLibraryManager::ShareLock"); + } curlLibraryManager; /** |