mirror of
https://github.com/transmission/transmission
synced 2025-01-30 10:52:00 +00:00
fix: conform to libcurl requirements to avoid memory leak (#5702)
This commit is contained in:
parent
f83a60830a
commit
2211086338
17 changed files with 78 additions and 39 deletions
|
@ -200,6 +200,8 @@ static std::string getConfigDir(int argc, char const** argv)
|
|||
|
||||
int tr_main(int argc, char* argv[])
|
||||
{
|
||||
auto const init_mgr = tr_lib_init();
|
||||
|
||||
tr_locale_set_global("");
|
||||
|
||||
tr_variant settings;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <libtransmission/tr-getopt.h>
|
||||
#include <libtransmission/tr-macros.h>
|
||||
#include <libtransmission/tr-strbuf.h>
|
||||
#include <libtransmission/utils.h>
|
||||
#include <libtransmission/version.h>
|
||||
#include <libtransmission/watchdir.h>
|
||||
|
||||
|
@ -691,9 +692,6 @@ int tr_daemon::start([[maybe_unused]] bool foreground)
|
|||
|
||||
sd_notifyf(0, "MAINPID=%d\n", (int)getpid());
|
||||
|
||||
/* should go before libevent calls */
|
||||
tr_net_init();
|
||||
|
||||
/* setup event state */
|
||||
ev_base_ = event_base_new();
|
||||
|
||||
|
@ -941,6 +939,8 @@ void tr_daemon::handle_error(tr_error* error) const
|
|||
|
||||
int tr_main(int argc, char* argv[])
|
||||
{
|
||||
auto const init_mgr = tr_lib_init();
|
||||
|
||||
tr_locale_set_global("");
|
||||
|
||||
int ret;
|
||||
|
|
|
@ -50,6 +50,9 @@ Glib::OptionEntry create_option_entry(Glib::ustring const& long_name, gchar shor
|
|||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
/* init libtransmission */
|
||||
auto const init_mgr = tr_lib_init();
|
||||
|
||||
/* init i18n */
|
||||
tr_locale_set_global("");
|
||||
bindtextdomain(AppTranslationDomainName, TRANSMISSIONLOCALEDIR);
|
||||
|
|
|
@ -113,8 +113,6 @@ unsigned long thread_current_id()
|
|||
|
||||
void initEvthreadsOnce()
|
||||
{
|
||||
tr_net_init();
|
||||
|
||||
evthread_lock_callbacks constexpr LockCbs{
|
||||
EVTHREAD_LOCK_API_VERSION, EVTHREAD_LOCKTYPE_RECURSIVE, lock_alloc, lock_free, lock_lock, lock_unlock
|
||||
};
|
||||
|
|
|
@ -272,8 +272,6 @@ private:
|
|||
*/
|
||||
bool initImpl(struct event_base* event_base)
|
||||
{
|
||||
tr_net_init();
|
||||
|
||||
int const opt_on = 1;
|
||||
|
||||
static_assert(AnnounceScope > 0);
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <cstdint> // SIZE_MAX
|
||||
#include <cstdlib> // getenv()
|
||||
#include <cstring> /* strerror() */
|
||||
#include <ctime> // nanosleep()
|
||||
#include <iostream>
|
||||
#include <iterator> // for std::back_inserter
|
||||
#include <locale>
|
||||
|
@ -19,14 +18,12 @@
|
|||
#include <set>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h> /* Sleep(), GetEnvironmentVariable() */
|
||||
|
||||
#include <shellapi.h> /* CommandLineToArgv() */
|
||||
#include <ws2tcpip.h> /* WSAStartup() */
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
|
@ -36,6 +33,8 @@
|
|||
#define UTF_CPP_CPLUSPLUS 201703L
|
||||
#include <utf8.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <fast_float/fast_float.h>
|
||||
|
@ -929,19 +928,36 @@ std::string tr_env_get_string(std::string_view key, std::string_view default_val
|
|||
|
||||
// ---
|
||||
|
||||
void tr_net_init()
|
||||
tr_net_init_mgr::tr_net_init_mgr()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
// try to init curl with default settings (currently ssl support + win32 sockets)
|
||||
// but if that fails, we need to init win32 sockets as a bare minimum
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
|
||||
{
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
|
||||
initialized = true;
|
||||
curl_global_init(CURL_GLOBAL_WIN32);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
tr_net_init_mgr::~tr_net_init_mgr()
|
||||
{
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
std::unique_ptr<tr_net_init_mgr> tr_net_init_mgr::create()
|
||||
{
|
||||
if (!initialised)
|
||||
{
|
||||
initialised = true;
|
||||
return std::unique_ptr<tr_net_init_mgr>{ new tr_net_init_mgr };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool tr_net_init_mgr::initialised = false;
|
||||
|
||||
std::unique_ptr<tr_net_init_mgr> tr_lib_init()
|
||||
{
|
||||
return tr_net_init_mgr::create();
|
||||
}
|
||||
|
||||
// --- mime-type
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <cstdint> // uint8_t, uint32_t, uint64_t
|
||||
#include <cstddef> // size_t
|
||||
#include <ctime> // time_t
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
@ -340,4 +341,20 @@ void tr_formatter_get_units(void* dict);
|
|||
|
||||
// ---
|
||||
|
||||
void tr_net_init();
|
||||
class tr_net_init_mgr
|
||||
{
|
||||
private:
|
||||
tr_net_init_mgr();
|
||||
TR_DISABLE_COPY_MOVE(tr_net_init_mgr)
|
||||
|
||||
public:
|
||||
~tr_net_init_mgr();
|
||||
static std::unique_ptr<tr_net_init_mgr> create();
|
||||
|
||||
private:
|
||||
static bool initialised;
|
||||
};
|
||||
|
||||
/** @brief Initialise libtransmission for each app
|
||||
* @return A manager object to be kept in scope of main() */
|
||||
std::unique_ptr<tr_net_init_mgr> tr_lib_init();
|
||||
|
|
|
@ -134,8 +134,6 @@ private:
|
|||
|
||||
void init(struct event_base* event_base)
|
||||
{
|
||||
tr_net_init();
|
||||
|
||||
auto const path = dirname();
|
||||
auto const wide_path = tr_win32_utf8_to_native(path);
|
||||
if (std::empty(wide_path))
|
||||
|
|
|
@ -160,8 +160,6 @@ public:
|
|||
explicit Impl(Mediator& mediator_in)
|
||||
: mediator{ mediator_in }
|
||||
{
|
||||
std::call_once(curl_init_flag, curlInit);
|
||||
|
||||
if (auto bundle = tr_env_get_string("CURL_CA_BUNDLE"); !std::empty(bundle))
|
||||
{
|
||||
curl_ca_bundle = std::move(bundle);
|
||||
|
@ -778,19 +776,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
static inline auto curl_init_flag = std::once_flag{};
|
||||
|
||||
std::map<CURL*, uint64_t /*tr_time_msec()*/> paused_easy_handles;
|
||||
|
||||
static void curlInit()
|
||||
{
|
||||
// try to enable ssl for https support;
|
||||
// but if that fails, try a plain vanilla init
|
||||
if (curl_global_init(CURL_GLOBAL_SSL) != CURLE_OK)
|
||||
{
|
||||
curl_global_init(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tr_web::tr_web(Mediator& mediator)
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
auto const init_mgr = tr_lib_init();
|
||||
|
||||
tr_locale_set_global("");
|
||||
|
||||
return NSApplicationMain(argc, (char const**)argv);
|
||||
|
|
|
@ -662,6 +662,8 @@ void Application::onNotificationActionInvoked(quint32 /* notification_id */, QSt
|
|||
|
||||
int tr_main(int argc, char** argv)
|
||||
{
|
||||
auto const init_mgr = tr_lib_init();
|
||||
|
||||
tr_locale_set_global("");
|
||||
|
||||
InteropHelper::initialize();
|
||||
|
|
|
@ -32,9 +32,8 @@ class AnnouncerUdpTest : public ::testing::Test
|
|||
private:
|
||||
void SetUp() override
|
||||
{
|
||||
tr_net_init();
|
||||
|
||||
::testing::Test::SetUp();
|
||||
init_mgr_ = tr_lib_init();
|
||||
tr_timeUpdate(time(nullptr));
|
||||
}
|
||||
|
||||
|
@ -288,6 +287,8 @@ protected:
|
|||
return timer;
|
||||
}
|
||||
|
||||
std::unique_ptr<tr_net_init_mgr> init_mgr_;
|
||||
|
||||
// https://www.bittorrent.org/beps/bep_0015.html
|
||||
static auto constexpr ProtocolId = uint64_t{ 0x41727101980ULL };
|
||||
static auto constexpr ConnectAction = uint32_t{ 0 };
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <libtransmission/file.h>
|
||||
#include <libtransmission/timer-ev.h>
|
||||
#include <libtransmission/utils.h>
|
||||
#include <libtransmission/session-thread.h> // for tr_evthread_init();
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
@ -388,6 +389,8 @@ protected:
|
|||
{
|
||||
SandboxedTest::SetUp();
|
||||
|
||||
init_mgr_ = tr_lib_init();
|
||||
|
||||
tr_session_thread::tr_evthread_init();
|
||||
event_base_ = event_base_new();
|
||||
}
|
||||
|
@ -402,6 +405,8 @@ protected:
|
|||
|
||||
struct event_base* event_base_ = nullptr;
|
||||
|
||||
std::unique_ptr<tr_net_init_mgr> init_mgr_;
|
||||
|
||||
// Arbitrary values. Several tests requires socket/port values
|
||||
// to be provided but they aren't central to the tests, so they're
|
||||
// declared here with "Arbitrary" in the name to make that clear.
|
||||
|
|
|
@ -530,6 +530,8 @@ protected:
|
|||
{
|
||||
SandboxedTest::SetUp();
|
||||
|
||||
init_mgr_ = tr_lib_init();
|
||||
|
||||
auto callback = [this](tr_torrent* tor, bool /*aborted*/)
|
||||
{
|
||||
auto verified_lock = std::scoped_lock(verified_mutex_);
|
||||
|
@ -554,6 +556,8 @@ private:
|
|||
std::mutex verified_mutex_;
|
||||
std::condition_variable verified_cv_;
|
||||
std::vector<tr_torrent*> verified_;
|
||||
|
||||
std::unique_ptr<tr_net_init_mgr> init_mgr_;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
|
|
@ -53,10 +53,13 @@ private:
|
|||
std::shared_ptr<struct event_base> ev_base_;
|
||||
std::unique_ptr<libtransmission::TimerMaker> timer_maker_;
|
||||
|
||||
std::unique_ptr<tr_net_init_mgr> init_mgr_;
|
||||
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
SandboxedTest::SetUp();
|
||||
init_mgr_ = tr_lib_init();
|
||||
ev_base_.reset(event_base_new(), event_base_free);
|
||||
timer_maker_ = std::make_unique<libtransmission::EvTimerMaker>(ev_base_.get());
|
||||
Watchdir::set_generic_rescan_interval(GenericRescanInterval);
|
||||
|
|
|
@ -3290,6 +3290,8 @@ static void getHostAndPortAndRpcUrl(int* argc, char** argv, std::string* host, i
|
|||
|
||||
int tr_main(int argc, char* argv[])
|
||||
{
|
||||
auto const init_mgr = tr_lib_init();
|
||||
|
||||
tr_locale_set_global("");
|
||||
|
||||
auto config = Config{};
|
||||
|
|
|
@ -398,6 +398,8 @@ void doScrape(tr_torrent_metainfo const& metainfo)
|
|||
|
||||
int tr_main(int argc, char* argv[])
|
||||
{
|
||||
auto const init_mgr = tr_lib_init();
|
||||
|
||||
tr_locale_set_global("");
|
||||
|
||||
tr_logSetQueueEnabled(false);
|
||||
|
|
Loading…
Reference in a new issue