-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
core-clp: Add class to encapsulate
libcurl
's global resource manage…
…ment. (#461) Co-authored-by: kirkrodrigues <2454684+kirkrodrigues@users.noreply.github.com>
- Loading branch information
1 parent
be1877d
commit 0837494
Showing
6 changed files
with
103 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include "CurlGlobalInstance.hpp" | ||
|
||
#include <mutex> | ||
|
||
#include <curl/curl.h> | ||
|
||
#include "CurlOperationFailed.hpp" | ||
#include "ErrorCode.hpp" | ||
|
||
namespace clp { | ||
CurlGlobalInstance::CurlGlobalInstance() { | ||
std::scoped_lock const global_lock{m_ref_count_mutex}; | ||
if (0 == m_ref_count) { | ||
if (auto const err{curl_global_init(CURL_GLOBAL_ALL)}; 0 != err) { | ||
throw CurlOperationFailed( | ||
ErrorCode_Failure, | ||
__FILE__, | ||
__LINE__, | ||
err, | ||
"`curl_global_init` failed." | ||
); | ||
} | ||
} | ||
++m_ref_count; | ||
} | ||
|
||
CurlGlobalInstance::~CurlGlobalInstance() { | ||
std::scoped_lock const global_lock{m_ref_count_mutex}; | ||
--m_ref_count; | ||
if (0 == m_ref_count) { | ||
#if defined(__APPLE__) | ||
// NOTE: On macOS, calling `curl_global_init` after `curl_global_cleanup` will fail with | ||
// CURLE_SSL_CONNECT_ERROR. Thus, for now, we skip `deinit` on macOS. Luckily, it is safe to | ||
// call `curl_global_init` multiple times without calling `curl_global_cleanup`. Related | ||
// issues: | ||
// - https://github.com/curl/curl/issues/12525 | ||
// - https://github.com/curl/curl/issues/13805 | ||
// TODO: Remove this conditional logic when the issues are resolved. | ||
return; | ||
#else | ||
curl_global_cleanup(); | ||
#endif | ||
} | ||
} | ||
} // namespace clp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#ifndef CLP_CURLGLOBALINSTANCE_HPP | ||
#define CLP_CURLGLOBALINSTANCE_HPP | ||
|
||
#include <cstddef> | ||
#include <mutex> | ||
|
||
namespace clp { | ||
/** | ||
* Class to wrap `libcurl`'s global initialization/de-initialization calls using RAII. Before using | ||
* any `libcurl` functionalities, an instance of this class must be created. Although unnecessasry, | ||
* it can be safely instantiated multiple times; it maintains a static reference count to all | ||
* existing instances and only de-initializes `libcurl`'s global resources when the reference count | ||
* reaches 0. | ||
*/ | ||
class CurlGlobalInstance { | ||
public: | ||
// Constructors | ||
CurlGlobalInstance(); | ||
|
||
// Disable copy/move constructors and assignment operators | ||
CurlGlobalInstance(CurlGlobalInstance const&) = delete; | ||
CurlGlobalInstance(CurlGlobalInstance&&) = delete; | ||
auto operator=(CurlGlobalInstance const&) -> CurlGlobalInstance& = delete; | ||
auto operator=(CurlGlobalInstance&&) -> CurlGlobalInstance& = delete; | ||
|
||
// Destructor | ||
~CurlGlobalInstance(); | ||
|
||
private: | ||
static inline std::mutex m_ref_count_mutex; | ||
static inline size_t m_ref_count{0}; | ||
}; | ||
} // namespace clp | ||
|
||
#endif // CLP_CURLGLOBALINSTANCE_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters