mirror of
https://github.com/transmission/transmission
synced 2025-01-01 04:26:34 +00:00
fix: tr_session field order (#3630)
This commit is contained in:
parent
3020e45f4b
commit
1c8032d23a
2 changed files with 69 additions and 97 deletions
|
@ -565,27 +565,6 @@ void tr_sessionSaveSettings(tr_session* session, char const* config_dir, tr_vari
|
||||||
****
|
****
|
||||||
***/
|
***/
|
||||||
|
|
||||||
/**
|
|
||||||
* Periodically save the .resume files of any torrents whose
|
|
||||||
* status has recently changed. This prevents loss of metadata
|
|
||||||
* in the case of a crash, unclean shutdown, clumsy user, etc.
|
|
||||||
*/
|
|
||||||
static void onSaveTimer(void* vsession)
|
|
||||||
{
|
|
||||||
auto* session = static_cast<tr_session*>(vsession);
|
|
||||||
|
|
||||||
for (auto* const tor : session->torrents())
|
|
||||||
{
|
|
||||||
tr_torrentSave(tor);
|
|
||||||
}
|
|
||||||
|
|
||||||
session->stats().saveIfDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
struct init_data
|
struct init_data
|
||||||
{
|
{
|
||||||
bool messageQueuingEnabled;
|
bool messageQueuingEnabled;
|
||||||
|
@ -645,25 +624,22 @@ tr_session* tr_sessionInit(char const* config_dir, bool message_queueing_enabled
|
||||||
|
|
||||||
static void turtleCheckClock(tr_session* s, struct tr_turtle_info* t);
|
static void turtleCheckClock(tr_session* s, struct tr_turtle_info* t);
|
||||||
|
|
||||||
static void onNowTimer(void* vsession)
|
void tr_session::onNowTimer()
|
||||||
{
|
{
|
||||||
auto* session = static_cast<tr_session*>(vsession);
|
TR_ASSERT(now_timer_);
|
||||||
|
|
||||||
TR_ASSERT(tr_isSession(session));
|
|
||||||
TR_ASSERT(session->now_timer_);
|
|
||||||
|
|
||||||
// tr_session upkeep tasks to perform once per second
|
// tr_session upkeep tasks to perform once per second
|
||||||
tr_timeUpdate(time(nullptr));
|
tr_timeUpdate(time(nullptr));
|
||||||
tr_dhtUpkeep(session);
|
tr_dhtUpkeep(this);
|
||||||
if (session->turtle.isClockEnabled)
|
if (turtle.isClockEnabled)
|
||||||
{
|
{
|
||||||
turtleCheckClock(session, &session->turtle);
|
turtleCheckClock(this, &this->turtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this seems a little silly. Why do we increment this
|
// TODO: this seems a little silly. Why do we increment this
|
||||||
// every second instead of computing the value as needed by
|
// every second instead of computing the value as needed by
|
||||||
// subtracting the current time from a start time?
|
// subtracting the current time from a start time?
|
||||||
for (auto* const tor : session->torrents())
|
for (auto* const tor : torrents())
|
||||||
{
|
{
|
||||||
if (tor->isRunning)
|
if (tor->isRunning)
|
||||||
{
|
{
|
||||||
|
@ -686,7 +662,7 @@ static void onNowTimer(void* vsession)
|
||||||
{
|
{
|
||||||
target_interval += 1s;
|
target_interval += 1s;
|
||||||
}
|
}
|
||||||
session->now_timer_->setInterval(std::chrono::duration_cast<std::chrono::milliseconds>(target_interval));
|
now_timer_->setInterval(std::chrono::duration_cast<std::chrono::milliseconds>(target_interval));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadBlocklists(tr_session* session);
|
static void loadBlocklists(tr_session* session);
|
||||||
|
@ -709,10 +685,6 @@ static void tr_sessionInitImpl(init_data* data)
|
||||||
tr_sessionGetDefaultSettings(&settings);
|
tr_sessionGetDefaultSettings(&settings);
|
||||||
tr_variantMergeDicts(&settings, clientSettings);
|
tr_variantMergeDicts(&settings, clientSettings);
|
||||||
|
|
||||||
session->now_timer_ = session->timerMaker().create();
|
|
||||||
session->now_timer_->setCallback(onNowTimer, session);
|
|
||||||
session->now_timer_->startRepeating(1s);
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/* Don't exit when writing on a broken socket */
|
/* Don't exit when writing on a broken socket */
|
||||||
(void)signal(SIGPIPE, SIG_IGN);
|
(void)signal(SIGPIPE, SIG_IGN);
|
||||||
|
@ -733,10 +705,6 @@ static void tr_sessionInitImpl(init_data* data)
|
||||||
|
|
||||||
TR_ASSERT(tr_isSession(session));
|
TR_ASSERT(tr_isSession(session));
|
||||||
|
|
||||||
session->save_timer_ = session->timerMaker().create();
|
|
||||||
session->save_timer_->setCallback(onSaveTimer, session);
|
|
||||||
session->save_timer_->startRepeating(SaveIntervalSecs);
|
|
||||||
|
|
||||||
tr_announcerInit(session);
|
tr_announcerInit(session);
|
||||||
|
|
||||||
tr_logAddInfo(fmt::format(_("Transmission version {version} starting"), fmt::arg("version", LONG_VERSION_STRING)));
|
tr_logAddInfo(fmt::format(_("Transmission version {version} starting"), fmt::arg("version", LONG_VERSION_STRING)));
|
||||||
|
@ -1838,32 +1806,30 @@ std::vector<tr_torrent*> tr_sessionGetTorrents(tr_session* session)
|
||||||
|
|
||||||
static void closeBlocklists(tr_session* /*session*/);
|
static void closeBlocklists(tr_session* /*session*/);
|
||||||
|
|
||||||
static void sessionCloseImplWaitForIdleUdp(void* vsession);
|
void tr_session::closeImplStart()
|
||||||
|
|
||||||
static void sessionCloseImplStart(tr_session* session)
|
|
||||||
{
|
{
|
||||||
session->is_closing_ = true;
|
is_closing_ = true;
|
||||||
|
|
||||||
if (session->isLPDEnabled)
|
if (isLPDEnabled)
|
||||||
{
|
{
|
||||||
tr_lpdUninit(session);
|
tr_lpdUninit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_dhtUninit(session);
|
tr_dhtUninit(this);
|
||||||
|
|
||||||
session->save_timer_.reset();
|
save_timer_.reset();
|
||||||
session->now_timer_.reset();
|
now_timer_.reset();
|
||||||
|
|
||||||
tr_verifyClose(session);
|
tr_verifyClose(this);
|
||||||
tr_sharedClose(*session);
|
tr_sharedClose(*this);
|
||||||
|
|
||||||
close_incoming_peer_port(session);
|
close_incoming_peer_port(this);
|
||||||
session->rpc_server_.reset();
|
this->rpc_server_.reset();
|
||||||
|
|
||||||
/* Close the torrents. Get the most active ones first so that
|
/* Close the torrents. Get the most active ones first so that
|
||||||
* if we can't get them all closed in a reasonable amount of time,
|
* if we can't get them all closed in a reasonable amount of time,
|
||||||
* at least we get the most important ones first. */
|
* at least we get the most important ones first. */
|
||||||
auto torrents = tr_sessionGetTorrents(session);
|
auto torrents = tr_sessionGetTorrents(this);
|
||||||
std::sort(
|
std::sort(
|
||||||
std::begin(torrents),
|
std::begin(torrents),
|
||||||
std::end(torrents),
|
std::end(torrents),
|
||||||
|
@ -1884,67 +1850,48 @@ static void sessionCloseImplStart(tr_session* session)
|
||||||
/* Close the announcer *after* closing the torrents
|
/* Close the announcer *after* closing the torrents
|
||||||
so that all the &event=stopped messages will be
|
so that all the &event=stopped messages will be
|
||||||
queued to be sent by tr_announcerClose() */
|
queued to be sent by tr_announcerClose() */
|
||||||
tr_announcerClose(session);
|
tr_announcerClose(this);
|
||||||
|
|
||||||
/* and this goes *after* announcer close so that
|
/* and this goes *after* announcer close so that
|
||||||
it won't be idle until the announce events are sent... */
|
it won't be idle until the announce events are sent... */
|
||||||
session->web->closeSoon();
|
this->web->closeSoon();
|
||||||
|
|
||||||
session->cache.reset();
|
this->cache.reset();
|
||||||
|
|
||||||
/* saveTimer is not used at this point, reusing for UDP shutdown wait */
|
/* saveTimer is not used at this point, reusing for UDP shutdown wait */
|
||||||
TR_ASSERT(!session->save_timer_);
|
TR_ASSERT(!save_timer_);
|
||||||
session->save_timer_ = session->timerMaker().create();
|
save_timer_ = timerMaker().create([this]() { closeImplWaitForIdleUdp(); });
|
||||||
session->save_timer_->setCallback(sessionCloseImplWaitForIdleUdp, session);
|
save_timer_->start(1ms);
|
||||||
session->save_timer_->start(1ms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sessionCloseImplFinish(tr_session* session);
|
void tr_session::closeImplWaitForIdleUdp()
|
||||||
|
|
||||||
static void sessionCloseImplWaitForIdleUdp(void* vsession)
|
|
||||||
{
|
{
|
||||||
auto* session = static_cast<tr_session*>(vsession);
|
|
||||||
|
|
||||||
TR_ASSERT(tr_isSession(session));
|
|
||||||
|
|
||||||
/* gotta keep udp running long enough to send out all
|
/* gotta keep udp running long enough to send out all
|
||||||
the &event=stopped UDP tracker messages */
|
the &event=stopped UDP tracker messages */
|
||||||
if (!tr_tracker_udp_is_idle(session))
|
if (!tr_tracker_udp_is_idle(this))
|
||||||
{
|
{
|
||||||
tr_tracker_udp_upkeep(session);
|
tr_tracker_udp_upkeep(this);
|
||||||
session->save_timer_->start(100ms);
|
save_timer_->start(100ms);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionCloseImplFinish(session);
|
closeImplFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sessionCloseImplFinish(tr_session* session)
|
void tr_session::closeImplFinish()
|
||||||
{
|
{
|
||||||
session->save_timer_.reset();
|
save_timer_.reset();
|
||||||
|
|
||||||
/* we had to wait until UDP trackers were closed before closing these: */
|
/* we had to wait until UDP trackers were closed before closing these: */
|
||||||
tr_tracker_udp_close(session);
|
tr_tracker_udp_close(this);
|
||||||
tr_udpUninit(session);
|
tr_udpUninit(this);
|
||||||
|
|
||||||
session->stats().saveIfDirty();
|
stats().saveIfDirty();
|
||||||
|
tr_peerMgrFree(peerMgr);
|
||||||
tr_peerMgrFree(session->peerMgr);
|
tr_utpClose(this);
|
||||||
|
closeBlocklists(this);
|
||||||
tr_utpClose(session);
|
openFiles().closeAll();
|
||||||
|
isClosed = true;
|
||||||
closeBlocklists(session);
|
|
||||||
|
|
||||||
session->openFiles().closeAll();
|
|
||||||
|
|
||||||
session->isClosed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sessionCloseImpl(tr_session* const session)
|
|
||||||
{
|
|
||||||
TR_ASSERT(tr_isSession(session));
|
|
||||||
|
|
||||||
sessionCloseImplStart(session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool deadlineReached(time_t const deadline)
|
static bool deadlineReached(time_t const deadline)
|
||||||
|
@ -1964,7 +1911,7 @@ void tr_sessionClose(tr_session* session)
|
||||||
tr_logAddDebug(fmt::format("now is {}, deadline is {}", time(nullptr), deadline));
|
tr_logAddDebug(fmt::format("now is {}, deadline is {}", time(nullptr), deadline));
|
||||||
|
|
||||||
/* close the session */
|
/* close the session */
|
||||||
tr_runInEventThread(session, sessionCloseImpl, session);
|
tr_runInEventThread(session, [session]() { session->closeImplStart(); });
|
||||||
|
|
||||||
while (!session->isClosed && !deadlineReached(deadline))
|
while (!session->isClosed && !deadlineReached(deadline))
|
||||||
{
|
{
|
||||||
|
@ -3017,4 +2964,21 @@ tr_session::tr_session(std::string_view config_dir)
|
||||||
, torrent_dir_{ makeTorrentDir(config_dir) }
|
, torrent_dir_{ makeTorrentDir(config_dir) }
|
||||||
, session_stats_{ config_dir, time(nullptr) }
|
, session_stats_{ config_dir, time(nullptr) }
|
||||||
{
|
{
|
||||||
|
now_timer_ = timerMaker().create([this]() { onNowTimer(); });
|
||||||
|
now_timer_->startRepeating(1s);
|
||||||
|
|
||||||
|
// Periodically save the .resume files of any torrents whose
|
||||||
|
// status has recently changed. This prevents loss of metadata
|
||||||
|
// in the case of a crash, unclean shutdown, clumsy user, etc.
|
||||||
|
save_timer_ = timerMaker().create(
|
||||||
|
[this]()
|
||||||
|
{
|
||||||
|
for (auto* const tor : torrents())
|
||||||
|
{
|
||||||
|
tr_torrentSave(tor);
|
||||||
|
}
|
||||||
|
|
||||||
|
stats().saveIfDirty();
|
||||||
|
});
|
||||||
|
save_timer_->startRepeating(SaveIntervalSecs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -582,9 +582,6 @@ public:
|
||||||
struct tr_announcer* announcer = nullptr;
|
struct tr_announcer* announcer = nullptr;
|
||||||
struct tr_announcer_udp* announcer_udp = nullptr;
|
struct tr_announcer_udp* announcer_udp = nullptr;
|
||||||
|
|
||||||
std::unique_ptr<libtransmission::Timer> now_timer_;
|
|
||||||
std::unique_ptr<libtransmission::Timer> save_timer_;
|
|
||||||
|
|
||||||
// monitors the "global pool" speeds
|
// monitors the "global pool" speeds
|
||||||
tr_bandwidth top_bandwidth_;
|
tr_bandwidth top_bandwidth_;
|
||||||
|
|
||||||
|
@ -607,11 +604,22 @@ public:
|
||||||
int peer_socket_tos_ = *tr_netTosFromName(TR_DEFAULT_PEER_SOCKET_TOS_STR);
|
int peer_socket_tos_ = *tr_netTosFromName(TR_DEFAULT_PEER_SOCKET_TOS_STR);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend void tr_sessionClose(tr_session* session);
|
||||||
|
|
||||||
|
void closeImplStart();
|
||||||
|
void closeImplWaitForIdleUdp();
|
||||||
|
void closeImplFinish();
|
||||||
|
|
||||||
static std::recursive_mutex session_mutex_;
|
static std::recursive_mutex session_mutex_;
|
||||||
|
|
||||||
std::shared_ptr<event_base> const event_base_;
|
std::shared_ptr<event_base> const event_base_;
|
||||||
std::unique_ptr<libtransmission::TimerMaker> const timer_maker_;
|
std::unique_ptr<libtransmission::TimerMaker> const timer_maker_;
|
||||||
|
|
||||||
|
void onNowTimer();
|
||||||
|
std::unique_ptr<libtransmission::Timer> now_timer_;
|
||||||
|
|
||||||
|
std::unique_ptr<libtransmission::Timer> save_timer_;
|
||||||
|
|
||||||
tr_torrents torrents_;
|
tr_torrents torrents_;
|
||||||
|
|
||||||
std::array<std::string, TR_SCRIPT_N_TYPES> scripts_;
|
std::array<std::string, TR_SCRIPT_N_TYPES> scripts_;
|
||||||
|
|
Loading…
Reference in a new issue