From 681f41527280e56b97e0632c79e07350db2f5690 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 26 Oct 2016 13:50:20 -0700 Subject: [PATCH] Use curl_global_init/curl_global_cleanup for cleaner shutdown of executable --- src/cpp-utils/CMakeLists.txt | 1 + src/cpp-utils/network/CurlHttpClient.cpp | 2 +- src/cpp-utils/network/CurlHttpClient.h | 3 ++- src/cpp-utils/network/CurlInitializerRAII.cpp | 27 +++++++++++++++++++ src/cpp-utils/network/CurlInitializerRAII.h | 27 +++++++++++++++++++ 5 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/cpp-utils/network/CurlInitializerRAII.cpp create mode 100644 src/cpp-utils/network/CurlInitializerRAII.h diff --git a/src/cpp-utils/CMakeLists.txt b/src/cpp-utils/CMakeLists.txt index 072600cf..a934bfed 100644 --- a/src/cpp-utils/CMakeLists.txt +++ b/src/cpp-utils/CMakeLists.txt @@ -12,6 +12,7 @@ set(SOURCES tempfile/TempDir.cpp network/HttpClient.cpp network/CurlHttpClient.cpp + network/CurlInitializerRAII.cpp network/FakeHttpClient.cpp io/Console.cpp io/DontEchoStdinToStdoutRAII.cpp diff --git a/src/cpp-utils/network/CurlHttpClient.cpp b/src/cpp-utils/network/CurlHttpClient.cpp index 317a3560..dcfd85f8 100644 --- a/src/cpp-utils/network/CurlHttpClient.cpp +++ b/src/cpp-utils/network/CurlHttpClient.cpp @@ -17,7 +17,7 @@ namespace cpputils { return size * nmemb; } - CurlHttpClient::CurlHttpClient() { + CurlHttpClient::CurlHttpClient(): curlInitializer(), curl() { curl = curl_easy_init(); } diff --git a/src/cpp-utils/network/CurlHttpClient.h b/src/cpp-utils/network/CurlHttpClient.h index 439335b8..49f859a8 100644 --- a/src/cpp-utils/network/CurlHttpClient.h +++ b/src/cpp-utils/network/CurlHttpClient.h @@ -4,7 +4,7 @@ #include "HttpClient.h" #include "../macros.h" -#include +#include "CurlInitializerRAII.h" namespace cpputils { @@ -17,6 +17,7 @@ namespace cpputils { boost::optional get(const std::string &url, boost::optional timeoutMsec = boost::none) override; private: + CurlInitializerRAII curlInitializer; CURL *curl; static size_t write_data(void *ptr, size_t size, size_t nmemb, std::ostringstream *stream); diff --git a/src/cpp-utils/network/CurlInitializerRAII.cpp b/src/cpp-utils/network/CurlInitializerRAII.cpp new file mode 100644 index 00000000..c9172852 --- /dev/null +++ b/src/cpp-utils/network/CurlInitializerRAII.cpp @@ -0,0 +1,27 @@ +#include "CurlInitializerRAII.h" + +using std::mutex; +using std::unique_lock; + +namespace cpputils { + +mutex CurlInitializerRAII::_mutex; +uint32_t CurlInitializerRAII::_refcount = 0; + +CurlInitializerRAII::CurlInitializerRAII() { + unique_lock lock(_mutex); + if (0 == _refcount) { + curl_global_init(CURL_GLOBAL_ALL); + } + _refcount += 1; +} + +CurlInitializerRAII::~CurlInitializerRAII() { + unique_lock lock(_mutex); + _refcount -= 1; + if (0 == _refcount) { + curl_global_cleanup(); + } +} + +} diff --git a/src/cpp-utils/network/CurlInitializerRAII.h b/src/cpp-utils/network/CurlInitializerRAII.h new file mode 100644 index 00000000..a95d7dc5 --- /dev/null +++ b/src/cpp-utils/network/CurlInitializerRAII.h @@ -0,0 +1,27 @@ +#pragma once +#ifndef MESSMER_CPPUTILS_NETWORK_CURLINITIALIZERRAII_HPP +#define MESSMER_CPPUTILS_NETWORK_CURLINITIALIZERRAII_HPP + +#include +#include +#include + +namespace cpputils { + // TODO Test + + // When the first object of this class is created, it will initialize curl using curl_global_init(). + // When the last object is destroyed, it will deinitialize curl using curl_global_cleanup(). + class CurlInitializerRAII final { + public: + CurlInitializerRAII(); + ~CurlInitializerRAII(); + private: + static std::mutex _mutex; + static uint32_t _refcount; + + DISALLOW_COPY_AND_ASSIGN(CurlInitializerRAII); + }; + +} + +#endif