From a28b07b3904b98d0115a0fc929d690ba10054d60 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 16 May 2022 13:48:43 -0500 Subject: [PATCH] Revert "refactor: move tr_torrent callbacks to tr_session (#3003)" (#3104) This reverts commit 27fbfd8da62d39127b891cb8dc481938fbf13d72. Fixes #3088. --- gtk/Session.cc | 24 ++++---- libtransmission/peer-mgr.cc | 5 +- libtransmission/session.cc | 24 -------- libtransmission/session.h | 75 ------------------------- libtransmission/torrent.cc | 88 ++++++++++++++++++++++++++++-- libtransmission/torrent.h | 15 +++++ libtransmission/transmission.h | 32 ++++++++--- macosx/Torrent.mm | 10 ++-- tests/libtransmission/move-test.cc | 2 +- 9 files changed, 145 insertions(+), 130 deletions(-) diff --git a/gtk/Session.cc b/gtk/Session.cc index 13a876f61..07f1d44a0 100644 --- a/gtk/Session.cc +++ b/gtk/Session.cc @@ -813,8 +813,8 @@ Session::Session(tr_session* session) Session::~Session() = default; Session::Impl::Impl(Session& core, tr_session* session) - : core_{ core } - , session_{ session } + : core_(core) + , session_(session) { raw_model_ = Gtk::ListStore::create(torrent_cols); sorted_model_ = Gtk::TreeModelSort::create(raw_model_); @@ -828,16 +828,6 @@ Session::Impl::Impl(Session& core, tr_session* session) on_pref_changed(TR_KEY_peer_limit_global); on_pref_changed(TR_KEY_inhibit_desktop_hibernation); signal_prefs_changed.connect([this](auto key) { on_pref_changed(key); }); - - tr_sessionSetMetadataCallback( - session_, - [](auto* tor2, gpointer impl) { static_cast(impl)->on_torrent_metadata_changed(tor2); }, - this); - tr_sessionSetCompletenessCallback( - session_, - [](auto* tor2, auto completeness, bool was_running, gpointer impl) - { static_cast(impl)->on_torrent_completeness_changed(tor2, completeness, was_running); }, - this); } tr_session* Session::close() @@ -996,6 +986,16 @@ void Session::Impl::add_torrent(tr_torrent* tor, bool do_notify) { gtr_notify_torrent_added(get_core_ptr(), tr_torrentId(tor)); } + + tr_torrentSetMetadataCallback( + tor, + [](auto* tor2, gpointer impl) { static_cast(impl)->on_torrent_metadata_changed(tor2); }, + this); + tr_torrentSetCompletenessCallback( + tor, + [](auto* tor2, auto completeness, bool was_running, gpointer impl) + { static_cast(impl)->on_torrent_completeness_changed(tor2, completeness, was_running); }, + this); } } diff --git a/libtransmission/peer-mgr.cc b/libtransmission/peer-mgr.cc index 5e530dd4c..f3744c3e1 100644 --- a/libtransmission/peer-mgr.cc +++ b/libtransmission/peer-mgr.cc @@ -2579,7 +2579,10 @@ static void queuePulse(tr_session* session, tr_direction dir) { tr_torrentStartNow(tor); - session->torrentQueueStarted(tor); + if (tor->queue_started_callback != nullptr) + { + (*tor->queue_started_callback)(tor, tor->queue_started_user_data); + } } } } diff --git a/libtransmission/session.cc b/libtransmission/session.cc index c7b89f18b..4c60c2ff5 100644 --- a/libtransmission/session.cc +++ b/libtransmission/session.cc @@ -2931,30 +2931,6 @@ static int bandwidthGroupWrite(tr_session const* session, std::string_view confi return ret; } -void tr_sessionSetQueueStartCallback(tr_session* session, tr_session::TorrentCallbackFunc callback, void* user_data) -{ - session->setTorrentQueueStartedCallback(callback, user_data); -} - -void tr_sessionSetMetadataCallback(tr_session* session, tr_session::TorrentCallbackFunc callback, void* user_data) -{ - session->setTorrentMetadataCallback(callback, user_data); -} - -void tr_sessionSetIdleLimitHitCallback(tr_session* session, tr_session::TorrentCallbackFunc callback, void* user_data) -{ - session->setTorrentIdleLimitCallback(callback, user_data); -} - -void tr_sessionSetRatioLimitHitCallback(tr_session* session, tr_session::TorrentCallbackFunc callback, void* user_data) -{ - session->setTorrentRatioLimitCallback(callback, user_data); -} - -void tr_sessionSetCompletenessCallback(tr_session* session, tr_session::CompletenessFunc func, void* user_data) -{ - session->setTorrentCompletenessCallback(func, user_data); -} /// void tr_session::closeTorrentFiles(tr_torrent* tor) noexcept diff --git a/libtransmission/session.h b/libtransmission/session.h index fb26caf88..e09496cc3 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -279,65 +279,6 @@ public: // - using TorrentCallbackFunc = void (*)(tr_torrent*, void* user_data); - - void setTorrentQueueStartedCallback(TorrentCallbackFunc cb, void* user_data) - { - queue_started_callback_ = std::make_pair(cb, user_data); - } - - void torrentQueueStarted(tr_torrent* tor) - { - invoke(tor, queue_started_callback_); - } - - void setTorrentMetadataCallback(TorrentCallbackFunc cb, void* user_data) - { - metadata_completed_callback_ = std::make_pair(cb, user_data); - } - - void torrentMetadataCompleted(tr_torrent* tor) - { - invoke(tor, metadata_completed_callback_); - } - - void setTorrentIdleLimitCallback(TorrentCallbackFunc cb, void* user_data) - { - idle_limit_callback_ = std::make_pair(cb, user_data); - } - - void torrentIdleLimitReached(tr_torrent* tor) - { - invoke(tor, idle_limit_callback_); - } - - void setTorrentRatioLimitCallback(TorrentCallbackFunc cb, void* user_data) - { - ratio_limit_callback_ = std::make_pair(cb, user_data); - } - - void torrentRatioLimitReached(tr_torrent* tor) - { - invoke(tor, ratio_limit_callback_); - } - - using CompletenessFunc = void (*)(tr_torrent*, tr_completeness, bool, void*); - - void setTorrentCompletenessCallback(CompletenessFunc cb, void* user_data) - { - torrent_completeness_callback_ = std::make_pair(cb, user_data); - } - - void torrentCompletenessChanged(tr_torrent* tor, tr_completeness completeness, bool was_running) - { - if (auto& [func, data] = torrent_completeness_callback_; func != nullptr) - { - func(tor, completeness, was_running, data); - } - } - - /// - [[nodiscard]] constexpr auto& openFiles() noexcept { return open_files_; @@ -503,16 +444,6 @@ public: int peer_socket_tos_ = *tr_netTosFromName(TR_DEFAULT_PEER_SOCKET_TOS_STR); private: - using TorrentCallback = std::pair; - - void invoke(tr_torrent* tor, TorrentCallback& cb) - { - if (auto& [func, data] = cb; func != nullptr) - { - func(tor, data); - } - } - static std::recursive_mutex session_mutex_; tr_torrents torrents_; @@ -525,12 +456,6 @@ private: std::string peer_congestion_algorithm_; std::optional external_ip_; - TorrentCallback idle_limit_callback_ = {}; - TorrentCallback metadata_completed_callback_ = {}; - TorrentCallback queue_started_callback_ = {}; - TorrentCallback ratio_limit_callback_ = {}; - std::pair torrent_completeness_callback_ = {}; - std::array scripts_enabled_; bool blocklist_enabled_ = false; bool incomplete_dir_enabled_ = false; diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index b95885c52..ed0dda395 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -466,7 +466,11 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor) tor->isStopping = true; - tor->session->torrentRatioLimitReached(tor); + /* maybe notify the client */ + if (tor->ratio_limit_hit_func != nullptr) + { + (*tor->ratio_limit_hit_func)(tor, tor->ratio_limit_hit_func_user_data); + } } /* if we're seeding and reach our inactivity limit, stop the torrent */ else if (tr_torrentIsSeedIdleLimitDone(tor)) @@ -475,7 +479,12 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor) tor->isStopping = true; tor->finishedSeedingByIdle = true; - tor->session->torrentIdleLimitReached(tor); + + /* maybe notify the client */ + if (tor->idle_limit_hit_func != nullptr) + { + (*tor->idle_limit_hit_func)(tor, tor->idle_limit_hit_func_user_data); + } } if (tor->isStopping) @@ -552,6 +561,8 @@ struct torrent_start_opts static void torrentStart(tr_torrent* tor, torrent_start_opts opts); +static void tr_torrentFireMetadataCompleted(tr_torrent* tor); + static void torrentInitFromInfoDict(tr_torrent* tor) { tor->completion = tr_completion{ tor, &tor->blockInfo() }; @@ -579,7 +590,7 @@ void tr_torrent::setMetainfo(tr_torrent_metainfo const& tm) torrentInitFromInfoDict(this); tr_peerMgrOnTorrentGotMetainfo(this); - this->session->torrentMetadataCompleted(this); + tr_torrentFireMetadataCompleted(this); this->setDirty(); } @@ -1617,6 +1628,7 @@ void tr_torrentFree(tr_torrent* tor) auto const lock = tor->unique_lock(); + tr_torrentClearCompletenessCallback(tor); tr_runInEventThread(session, closeTorrent, tor); } } @@ -1643,6 +1655,7 @@ static void removeTorrentInEventThread(tr_torrent* tor, bool delete_flag, tr_fil tor->metainfo_.files().remove(tor->currentDir(), tor->name(), delete_func_wrapper); } + tr_torrentClearCompletenessCallback(tor); closeTorrent(tor); } @@ -1679,6 +1692,45 @@ static char const* getCompletionString(int type) } } +static void fireCompletenessChange(tr_torrent* tor, tr_completeness status, bool wasRunning) +{ + TR_ASSERT(status == TR_LEECH || status == TR_SEED || status == TR_PARTIAL_SEED); + + if (tor->completeness_func != nullptr) + { + (*tor->completeness_func)(tor, status, wasRunning, tor->completeness_func_user_data); + } +} + +void tr_torrentSetCompletenessCallback(tr_torrent* tor, tr_torrent_completeness_func func, void* user_data) +{ + TR_ASSERT(tr_isTorrent(tor)); + + tor->completeness_func = func; + tor->completeness_func_user_data = user_data; +} + +void tr_torrentClearCompletenessCallback(tr_torrent* torrent) +{ + tr_torrentSetCompletenessCallback(torrent, nullptr, nullptr); +} + +void tr_torrentSetRatioLimitHitCallback(tr_torrent* tor, tr_torrent_ratio_limit_hit_func func, void* user_data) +{ + TR_ASSERT(tr_isTorrent(tor)); + + tor->ratio_limit_hit_func = func; + tor->ratio_limit_hit_func_user_data = user_data; +} + +void tr_torrentSetIdleLimitHitCallback(tr_torrent* tor, tr_torrent_idle_limit_hit_func func, void* user_data) +{ + TR_ASSERT(tr_isTorrent(tor)); + + tor->idle_limit_hit_func = func; + tor->idle_limit_hit_func_user_data = user_data; +} + static std::string buildLabelsString(tr_torrent const* tor) { auto buf = std::stringstream{}; @@ -1805,7 +1857,7 @@ void tr_torrent::recheckCompleteness() } } - this->session->torrentCompletenessChanged(this, completeness, wasRunning); + fireCompletenessChange(this, completeness, wasRunning); if (this->isDone() && wasLeeching && wasRunning) { @@ -1824,6 +1876,28 @@ void tr_torrent::recheckCompleteness() } } +/*** +**** +***/ + +static void tr_torrentFireMetadataCompleted(tr_torrent* tor) +{ + TR_ASSERT(tr_isTorrent(tor)); + + if (tor->metadata_func != nullptr) + { + (*tor->metadata_func)(tor, tor->metadata_func_user_data); + } +} + +void tr_torrentSetMetadataCallback(tr_torrent* tor, tr_torrent_metadata_func func, void* user_data) +{ + TR_ASSERT(tr_isTorrent(tor)); + + tor->metadata_func = func; + tor->metadata_func_user_data = user_data; +} + /** *** File DND **/ @@ -2480,6 +2554,12 @@ static void torrentSetQueued(tr_torrent* tor, bool queued) } } +void tr_torrentSetQueueStartCallback(tr_torrent* torrent, void (*callback)(tr_torrent*, void*), void* user_data) +{ + torrent->queue_started_callback = callback; + torrent->queue_started_user_data = user_data; +} + /*** **** **** RENAME diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index 9c56a7e02..19ddc07f4 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -650,6 +650,21 @@ public: * other peers */ struct tr_incomplete_metadata* incompleteMetadata = nullptr; + tr_torrent_metadata_func metadata_func = nullptr; + void* metadata_func_user_data = nullptr; + + tr_torrent_completeness_func completeness_func = nullptr; + void* completeness_func_user_data = nullptr; + + tr_torrent_ratio_limit_hit_func ratio_limit_hit_func = nullptr; + void* ratio_limit_hit_func_user_data = nullptr; + + tr_torrent_idle_limit_hit_func idle_limit_hit_func = nullptr; + void* idle_limit_hit_func_user_data = nullptr; + + void* queue_started_user_data = nullptr; + void (*queue_started_callback)(tr_torrent*, void* queue_started_user_data) = nullptr; + time_t peer_id_creation_time_ = 0; time_t dhtAnnounceAt = 0; diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index 3bb5020a4..09f40330a 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -691,8 +691,11 @@ void tr_sessionSetQueueStalledEnabled(tr_session*, bool); /** @return true if we're torrents idle for over N minutes will be flagged as 'stalled' */ bool tr_sessionGetQueueStalledEnabled(tr_session const*); +/** +**/ + /** @brief Set a callback that is invoked when the queue starts a torrent */ -void tr_sessionSetQueueStartCallback(tr_session* session, void (*callback)(tr_torrent*, void*), void* user_data); +void tr_torrentSetQueueStartCallback(tr_torrent* torrent, void (*callback)(tr_torrent*, void*), void* user_data); /*** **** @@ -1161,6 +1164,20 @@ enum tr_completeness TR_PARTIAL_SEED /* has the desired pieces, but not the entire torrent */ }; +/** + * @param wasRunning whether or not the torrent was running when + * it changed its completeness state + */ +using tr_torrent_completeness_func = void (*)( // + tr_torrent* torrent, + tr_completeness completeness, + bool wasRunning, + void* user_data); + +using tr_torrent_ratio_limit_hit_func = void (*)(tr_torrent* torrent, void* user_data); + +using tr_torrent_idle_limit_hit_func = void (*)(tr_torrent* torrent, void* user_data); + /** * Register to be notified whenever a torrent's "completeness" * changes. This will be called, for example, when a torrent @@ -1174,10 +1191,9 @@ enum tr_completeness * * @see tr_completeness */ -void tr_sessionSetCompletenessCallback( - tr_session*, - void (*callback)(tr_torrent*, tr_completeness, bool was_running, void*), - void* user_data); +void tr_torrentSetCompletenessCallback(tr_torrent* torrent, tr_torrent_completeness_func func, void* user_data); + +void tr_torrentClearCompletenessCallback(tr_torrent* torrent); using tr_torrent_metadata_func = void (*)(tr_torrent* torrent, void* user_data); @@ -1187,7 +1203,7 @@ using tr_torrent_metadata_func = void (*)(tr_torrent* torrent, void* user_data); * This happens when a magnet link finishes downloading * metadata from its peers. */ -void tr_sessionSetMetadataCallback(tr_session*, void (*callback)(tr_torrent*, void*), void* user_data); +void tr_torrentSetMetadataCallback(tr_torrent* tor, tr_torrent_metadata_func func, void* user_data); /** * Register to be notified whenever a torrent's ratio limit @@ -1196,7 +1212,7 @@ void tr_sessionSetMetadataCallback(tr_session*, void (*callback)(tr_torrent*, vo * * Has the same restrictions as tr_torrentSetCompletenessCallback */ -void tr_sessionSetRatioLimitHitCallback(tr_session*, void (*callback)(tr_torrent*, void*), void* user_data); +void tr_torrentSetRatioLimitHitCallback(tr_torrent* torrent, tr_torrent_ratio_limit_hit_func func, void* user_data); /** * Register to be notified whenever a torrent's idle limit @@ -1205,7 +1221,7 @@ void tr_sessionSetRatioLimitHitCallback(tr_session*, void (*callback)(tr_torrent * * Has the same restrictions as tr_torrentSetCompletenessCallback */ -void tr_sessionSetIdleLimitHitCallback(tr_session*, void (*callback)(tr_torrent*, void*), void* user_data); +void tr_torrentSetIdleLimitHitCallback(tr_torrent* torrent, tr_torrent_idle_limit_hit_func func, void* user_data); /** * MANUAL ANNOUNCE diff --git a/macosx/Torrent.mm b/macosx/Torrent.mm index b737e0713..80c7a84b0 100644 --- a/macosx/Torrent.mm +++ b/macosx/Torrent.mm @@ -1812,11 +1812,11 @@ bool trashDataFile(char const* filename, tr_error** error) } } - tr_sessionSetQueueStartCallback(lib, startQueueCallback, (__bridge void*)(self)); - tr_sessionSetCompletenessCallback(lib, completenessChangeCallback, (__bridge void*)(self)); - tr_sessionSetRatioLimitHitCallback(lib, ratioLimitHitCallback, (__bridge void*)(self)); - tr_sessionSetIdleLimitHitCallback(lib, idleLimitHitCallback, (__bridge void*)(self)); - tr_sessionSetMetadataCallback(lib, metadataCallback, (__bridge void*)(self)); + tr_torrentSetQueueStartCallback(self.fHandle, startQueueCallback, (__bridge void*)(self)); + tr_torrentSetCompletenessCallback(self.fHandle, completenessChangeCallback, (__bridge void*)(self)); + tr_torrentSetRatioLimitHitCallback(self.fHandle, ratioLimitHitCallback, (__bridge void*)(self)); + tr_torrentSetIdleLimitHitCallback(self.fHandle, idleLimitHitCallback, (__bridge void*)(self)); + tr_torrentSetMetadataCallback(self.fHandle, metadataCallback, (__bridge void*)(self)); _fResumeOnWake = NO; diff --git a/tests/libtransmission/move-test.cc b/tests/libtransmission/move-test.cc index 08d0e121b..b3366346d 100644 --- a/tests/libtransmission/move-test.cc +++ b/tests/libtransmission/move-test.cc @@ -73,7 +73,7 @@ TEST_P(IncompleteDirTest, incompleteDir) { *static_cast(vc) = c; }; - tr_sessionSetCompletenessCallback(session_, zeroes_completeness_func, &completeness); + tr_torrentSetCompletenessCallback(tor, zeroes_completeness_func, &completeness); struct TestIncompleteDirData {