mirror of
https://github.com/transmission/transmission
synced 2025-03-17 17:25:32 +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[])
|
int tr_main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
auto const init_mgr = tr_lib_init();
|
||||||
|
|
||||||
tr_locale_set_global("");
|
tr_locale_set_global("");
|
||||||
|
|
||||||
tr_variant settings;
|
tr_variant settings;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <libtransmission/tr-getopt.h>
|
#include <libtransmission/tr-getopt.h>
|
||||||
#include <libtransmission/tr-macros.h>
|
#include <libtransmission/tr-macros.h>
|
||||||
#include <libtransmission/tr-strbuf.h>
|
#include <libtransmission/tr-strbuf.h>
|
||||||
|
#include <libtransmission/utils.h>
|
||||||
#include <libtransmission/version.h>
|
#include <libtransmission/version.h>
|
||||||
#include <libtransmission/watchdir.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());
|
sd_notifyf(0, "MAINPID=%d\n", (int)getpid());
|
||||||
|
|
||||||
/* should go before libevent calls */
|
|
||||||
tr_net_init();
|
|
||||||
|
|
||||||
/* setup event state */
|
/* setup event state */
|
||||||
ev_base_ = event_base_new();
|
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[])
|
int tr_main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
auto const init_mgr = tr_lib_init();
|
||||||
|
|
||||||
tr_locale_set_global("");
|
tr_locale_set_global("");
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -50,6 +50,9 @@ Glib::OptionEntry create_option_entry(Glib::ustring const& long_name, gchar shor
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
/* init libtransmission */
|
||||||
|
auto const init_mgr = tr_lib_init();
|
||||||
|
|
||||||
/* init i18n */
|
/* init i18n */
|
||||||
tr_locale_set_global("");
|
tr_locale_set_global("");
|
||||||
bindtextdomain(AppTranslationDomainName, TRANSMISSIONLOCALEDIR);
|
bindtextdomain(AppTranslationDomainName, TRANSMISSIONLOCALEDIR);
|
||||||
|
|
|
@ -113,8 +113,6 @@ unsigned long thread_current_id()
|
||||||
|
|
||||||
void initEvthreadsOnce()
|
void initEvthreadsOnce()
|
||||||
{
|
{
|
||||||
tr_net_init();
|
|
||||||
|
|
||||||
evthread_lock_callbacks constexpr LockCbs{
|
evthread_lock_callbacks constexpr LockCbs{
|
||||||
EVTHREAD_LOCK_API_VERSION, EVTHREAD_LOCKTYPE_RECURSIVE, lock_alloc, lock_free, lock_lock, lock_unlock
|
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)
|
bool initImpl(struct event_base* event_base)
|
||||||
{
|
{
|
||||||
tr_net_init();
|
|
||||||
|
|
||||||
int const opt_on = 1;
|
int const opt_on = 1;
|
||||||
|
|
||||||
static_assert(AnnounceScope > 0);
|
static_assert(AnnounceScope > 0);
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <cstdint> // SIZE_MAX
|
#include <cstdint> // SIZE_MAX
|
||||||
#include <cstdlib> // getenv()
|
#include <cstdlib> // getenv()
|
||||||
#include <cstring> /* strerror() */
|
#include <cstring> /* strerror() */
|
||||||
#include <ctime> // nanosleep()
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iterator> // for std::back_inserter
|
#include <iterator> // for std::back_inserter
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
@ -19,14 +18,12 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <tuple>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h> /* Sleep(), GetEnvironmentVariable() */
|
#include <windows.h> /* Sleep(), GetEnvironmentVariable() */
|
||||||
|
|
||||||
#include <shellapi.h> /* CommandLineToArgv() */
|
#include <shellapi.h> /* CommandLineToArgv() */
|
||||||
#include <ws2tcpip.h> /* WSAStartup() */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -36,6 +33,8 @@
|
||||||
#define UTF_CPP_CPLUSPLUS 201703L
|
#define UTF_CPP_CPLUSPLUS 201703L
|
||||||
#include <utf8.h>
|
#include <utf8.h>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
|
|
||||||
#include <fast_float/fast_float.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
|
// try to init curl with default settings (currently ssl support + win32 sockets)
|
||||||
static bool initialized = false;
|
// but if that fails, we need to init win32 sockets as a bare minimum
|
||||||
|
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
|
||||||
if (!initialized)
|
|
||||||
{
|
{
|
||||||
WSADATA wsaData;
|
curl_global_init(CURL_GLOBAL_WIN32);
|
||||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
|
||||||
|
|
||||||
initialized = true;
|
|
||||||
}
|
}
|
||||||
#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
|
// --- mime-type
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <cstdint> // uint8_t, uint32_t, uint64_t
|
#include <cstdint> // uint8_t, uint32_t, uint64_t
|
||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <ctime> // time_t
|
#include <ctime> // time_t
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#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)
|
void init(struct event_base* event_base)
|
||||||
{
|
{
|
||||||
tr_net_init();
|
|
||||||
|
|
||||||
auto const path = dirname();
|
auto const path = dirname();
|
||||||
auto const wide_path = tr_win32_utf8_to_native(path);
|
auto const wide_path = tr_win32_utf8_to_native(path);
|
||||||
if (std::empty(wide_path))
|
if (std::empty(wide_path))
|
||||||
|
|
|
@ -160,8 +160,6 @@ public:
|
||||||
explicit Impl(Mediator& mediator_in)
|
explicit Impl(Mediator& mediator_in)
|
||||||
: 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))
|
if (auto bundle = tr_env_get_string("CURL_CA_BUNDLE"); !std::empty(bundle))
|
||||||
{
|
{
|
||||||
curl_ca_bundle = std::move(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;
|
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)
|
tr_web::tr_web(Mediator& mediator)
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
auto const init_mgr = tr_lib_init();
|
||||||
|
|
||||||
tr_locale_set_global("");
|
tr_locale_set_global("");
|
||||||
|
|
||||||
return NSApplicationMain(argc, (char const**)argv);
|
return NSApplicationMain(argc, (char const**)argv);
|
||||||
|
|
|
@ -662,6 +662,8 @@ void Application::onNotificationActionInvoked(quint32 /* notification_id */, QSt
|
||||||
|
|
||||||
int tr_main(int argc, char** argv)
|
int tr_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
auto const init_mgr = tr_lib_init();
|
||||||
|
|
||||||
tr_locale_set_global("");
|
tr_locale_set_global("");
|
||||||
|
|
||||||
InteropHelper::initialize();
|
InteropHelper::initialize();
|
||||||
|
|
|
@ -32,9 +32,8 @@ class AnnouncerUdpTest : public ::testing::Test
|
||||||
private:
|
private:
|
||||||
void SetUp() override
|
void SetUp() override
|
||||||
{
|
{
|
||||||
tr_net_init();
|
|
||||||
|
|
||||||
::testing::Test::SetUp();
|
::testing::Test::SetUp();
|
||||||
|
init_mgr_ = tr_lib_init();
|
||||||
tr_timeUpdate(time(nullptr));
|
tr_timeUpdate(time(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +287,8 @@ protected:
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<tr_net_init_mgr> init_mgr_;
|
||||||
|
|
||||||
// https://www.bittorrent.org/beps/bep_0015.html
|
// https://www.bittorrent.org/beps/bep_0015.html
|
||||||
static auto constexpr ProtocolId = uint64_t{ 0x41727101980ULL };
|
static auto constexpr ProtocolId = uint64_t{ 0x41727101980ULL };
|
||||||
static auto constexpr ConnectAction = uint32_t{ 0 };
|
static auto constexpr ConnectAction = uint32_t{ 0 };
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include <libtransmission/file.h>
|
#include <libtransmission/file.h>
|
||||||
#include <libtransmission/timer-ev.h>
|
#include <libtransmission/timer-ev.h>
|
||||||
|
#include <libtransmission/utils.h>
|
||||||
#include <libtransmission/session-thread.h> // for tr_evthread_init();
|
#include <libtransmission/session-thread.h> // for tr_evthread_init();
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
@ -388,6 +389,8 @@ protected:
|
||||||
{
|
{
|
||||||
SandboxedTest::SetUp();
|
SandboxedTest::SetUp();
|
||||||
|
|
||||||
|
init_mgr_ = tr_lib_init();
|
||||||
|
|
||||||
tr_session_thread::tr_evthread_init();
|
tr_session_thread::tr_evthread_init();
|
||||||
event_base_ = event_base_new();
|
event_base_ = event_base_new();
|
||||||
}
|
}
|
||||||
|
@ -402,6 +405,8 @@ protected:
|
||||||
|
|
||||||
struct event_base* event_base_ = nullptr;
|
struct event_base* event_base_ = nullptr;
|
||||||
|
|
||||||
|
std::unique_ptr<tr_net_init_mgr> init_mgr_;
|
||||||
|
|
||||||
// Arbitrary values. Several tests requires socket/port values
|
// Arbitrary values. Several tests requires socket/port values
|
||||||
// to be provided but they aren't central to the tests, so they're
|
// 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.
|
// declared here with "Arbitrary" in the name to make that clear.
|
||||||
|
|
|
@ -530,6 +530,8 @@ protected:
|
||||||
{
|
{
|
||||||
SandboxedTest::SetUp();
|
SandboxedTest::SetUp();
|
||||||
|
|
||||||
|
init_mgr_ = tr_lib_init();
|
||||||
|
|
||||||
auto callback = [this](tr_torrent* tor, bool /*aborted*/)
|
auto callback = [this](tr_torrent* tor, bool /*aborted*/)
|
||||||
{
|
{
|
||||||
auto verified_lock = std::scoped_lock(verified_mutex_);
|
auto verified_lock = std::scoped_lock(verified_mutex_);
|
||||||
|
@ -554,6 +556,8 @@ private:
|
||||||
std::mutex verified_mutex_;
|
std::mutex verified_mutex_;
|
||||||
std::condition_variable verified_cv_;
|
std::condition_variable verified_cv_;
|
||||||
std::vector<tr_torrent*> verified_;
|
std::vector<tr_torrent*> verified_;
|
||||||
|
|
||||||
|
std::unique_ptr<tr_net_init_mgr> init_mgr_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
|
|
|
@ -53,10 +53,13 @@ private:
|
||||||
std::shared_ptr<struct event_base> ev_base_;
|
std::shared_ptr<struct event_base> ev_base_;
|
||||||
std::unique_ptr<libtransmission::TimerMaker> timer_maker_;
|
std::unique_ptr<libtransmission::TimerMaker> timer_maker_;
|
||||||
|
|
||||||
|
std::unique_ptr<tr_net_init_mgr> init_mgr_;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override
|
void SetUp() override
|
||||||
{
|
{
|
||||||
SandboxedTest::SetUp();
|
SandboxedTest::SetUp();
|
||||||
|
init_mgr_ = tr_lib_init();
|
||||||
ev_base_.reset(event_base_new(), event_base_free);
|
ev_base_.reset(event_base_new(), event_base_free);
|
||||||
timer_maker_ = std::make_unique<libtransmission::EvTimerMaker>(ev_base_.get());
|
timer_maker_ = std::make_unique<libtransmission::EvTimerMaker>(ev_base_.get());
|
||||||
Watchdir::set_generic_rescan_interval(GenericRescanInterval);
|
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[])
|
int tr_main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
auto const init_mgr = tr_lib_init();
|
||||||
|
|
||||||
tr_locale_set_global("");
|
tr_locale_set_global("");
|
||||||
|
|
||||||
auto config = Config{};
|
auto config = Config{};
|
||||||
|
|
|
@ -398,6 +398,8 @@ void doScrape(tr_torrent_metainfo const& metainfo)
|
||||||
|
|
||||||
int tr_main(int argc, char* argv[])
|
int tr_main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
auto const init_mgr = tr_lib_init();
|
||||||
|
|
||||||
tr_locale_set_global("");
|
tr_locale_set_global("");
|
||||||
|
|
||||||
tr_logSetQueueEnabled(false);
|
tr_logSetQueueEnabled(false);
|
||||||
|
|
Loading…
Add table
Reference in a new issue