refactor: replace per-torrent callbacks with per-session ones. (#3495)

This commit is contained in:
Charles Kerr 2022-07-23 01:04:34 -05:00 committed by GitHub
parent 445aad56a0
commit 47fe7c47d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 209 additions and 188 deletions

View File

@ -828,6 +828,17 @@ 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* /*session*/, auto* tor, gpointer impl) { static_cast<Impl*>(impl)->on_torrent_metadata_changed(tor); },
this);
tr_sessionSetCompletenessCallback(
session,
[](auto* tor, auto completeness, bool was_running, gpointer impl)
{ static_cast<Impl*>(impl)->on_torrent_completeness_changed(tor, completeness, was_running); },
this);
}
tr_session* Session::close()
@ -986,16 +997,6 @@ 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*>(impl)->on_torrent_metadata_changed(tor2); },
this);
tr_torrentSetCompletenessCallback(
tor,
[](auto* tor2, auto completeness, bool was_running, gpointer impl)
{ static_cast<Impl*>(impl)->on_torrent_completeness_changed(tor2, completeness, was_running); },
this);
}
}

View File

@ -93,20 +93,6 @@ bool check_ccrypto_result(CCCryptorStatus result, char const* file, int line)
#define check_result(result) check_ccrypto_result((result), __FILE__, __LINE__)
bool check_ccrypto_pointer(void const* pointer, CCCryptorStatus const* result, char const* file, int line)
{
bool const ret = pointer != nullptr;
if (!ret)
{
log_ccrypto_error(*result, file, line);
}
return ret;
}
#define check_pointer(pointer, result) check_ccrypto_pointer((pointer), (result), __FILE__, __LINE__)
} // namespace
/***

View File

@ -2546,11 +2546,7 @@ void queuePulse(tr_session* session, tr_direction dir)
for (auto* tor : tr_sessionGetNextQueuedTorrents(session, dir, n))
{
tr_torrentStartNow(tor);
if (tor->queue_started_callback != nullptr)
{
(*tor->queue_started_callback)(tor, tor->queue_started_user_data);
}
session->onQueuedTorrentStarted(tor);
}
}
}

View File

@ -2968,3 +2968,30 @@ void tr_session::closeTorrentFile(tr_torrent* tor, tr_file_index_t file_num) noe
this->cache->flushFile(tor, file_num);
openFiles().closeFile(tor->id(), file_num);
}
///
void tr_sessionSetQueueStartCallback(tr_session* session, void (*cb)(tr_session*, tr_torrent*, void*), void* user_data)
{
session->setQueueStartCallback(cb, user_data);
}
void tr_sessionSetRatioLimitHitCallback(tr_session* session, tr_session_ratio_limit_hit_func cb, void* user_data)
{
session->setRatioLimitHitCallback(cb, user_data);
}
void tr_sessionSetIdleLimitHitCallback(tr_session* session, tr_session_idle_limit_hit_func cb, void* user_data)
{
session->setIdleLimitHitCallback(cb, user_data);
}
void tr_sessionSetMetadataCallback(tr_session* session, tr_session_metadata_func func, void* user_data)
{
session->setMetadataCallback(func, user_data);
}
void tr_sessionSetCompletenessCallback(tr_session* session, tr_torrent_completeness_func cb, void* user_data)
{
session->setTorrentCompletenessCallback(cb, user_data);
}

View File

@ -310,6 +310,80 @@ public:
announce_ip_enabled_ = enabled;
}
// callbacks
using queue_start_callback_t = void (*)(tr_session*, tr_torrent*, void* user_data);
void setQueueStartCallback(queue_start_callback_t cb, void* user_data)
{
queue_start_callback_ = cb;
queue_start_user_data_ = user_data;
}
void onQueuedTorrentStarted(tr_torrent* tor)
{
if (queue_start_callback_ != nullptr)
{
queue_start_callback_(this, tor, queue_start_user_data_);
}
}
void setIdleLimitHitCallback(tr_session_idle_limit_hit_func cb, void* user_data)
{
idle_limit_hit_callback_ = cb;
idle_limit_hit_user_data_ = user_data;
}
void onIdleLimitHit(tr_torrent* tor)
{
if (idle_limit_hit_callback_ != nullptr)
{
idle_limit_hit_callback_(this, tor, idle_limit_hit_user_data_);
}
}
void setRatioLimitHitCallback(tr_session_ratio_limit_hit_func cb, void* user_data)
{
ratio_limit_hit_cb_ = cb;
ratio_limit_hit_user_data_ = user_data;
}
void onRatioLimitHit(tr_torrent* tor)
{
if (ratio_limit_hit_cb_ != nullptr)
{
ratio_limit_hit_cb_(this, tor, ratio_limit_hit_user_data_);
}
}
void setMetadataCallback(tr_session_metadata_func cb, void* user_data)
{
got_metadata_cb_ = cb;
got_metadata_user_data_ = user_data;
}
void onMetadataCompleted(tr_torrent* tor)
{
if (got_metadata_cb_ != nullptr)
{
got_metadata_cb_(this, tor, got_metadata_user_data_);
}
}
void setTorrentCompletenessCallback(tr_torrent_completeness_func cb, void* user_data)
{
completeness_func_ = cb;
completeness_func_user_data_ = user_data;
}
void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness completeness, bool was_running)
{
if (completeness_func_ != nullptr)
{
completeness_func_(tor, completeness, was_running, completeness_func_user_data_);
}
}
public:
static constexpr std::array<std::tuple<tr_quark, tr_quark, TrScript>, 3> Scripts{
{ { TR_KEY_script_torrent_added_enabled, TR_KEY_script_torrent_added_filename, TR_SCRIPT_ON_TORRENT_ADDED },
@ -480,6 +554,21 @@ private:
std::string peer_congestion_algorithm_;
std::optional<tr_address> external_ip_;
queue_start_callback_t queue_start_callback_ = nullptr;
void* queue_start_user_data_ = nullptr;
tr_session_idle_limit_hit_func idle_limit_hit_callback_ = nullptr;
void* idle_limit_hit_user_data_ = nullptr;
tr_session_ratio_limit_hit_func ratio_limit_hit_cb_ = nullptr;
void* ratio_limit_hit_user_data_ = nullptr;
tr_session_metadata_func got_metadata_cb_ = nullptr;
void* got_metadata_user_data_ = nullptr;
tr_torrent_completeness_func completeness_func_ = nullptr;
void* completeness_func_user_data_ = nullptr;
std::array<bool, TR_SCRIPT_N_TYPES> scripts_enabled_;
bool blocklist_enabled_ = false;
bool incomplete_dir_enabled_ = false;

View File

@ -486,14 +486,8 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor)
if (tr_torrentIsSeedRatioDone(tor))
{
tr_logAddInfoTor(tor, _("Seed ratio reached; pausing torrent"));
tor->isStopping = true;
/* maybe notify the client */
if (tor->ratio_limit_hit_func != nullptr)
{
(*tor->ratio_limit_hit_func)(tor, tor->ratio_limit_hit_func_user_data);
}
tor->session->onRatioLimitHit(tor);
}
/* if we're seeding and reach our inactivity limit, stop the torrent */
else if (tr_torrentIsSeedIdleLimitDone(tor))
@ -502,12 +496,7 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor)
tor->isStopping = true;
tor->finishedSeedingByIdle = true;
/* maybe notify the client */
if (tor->idle_limit_hit_func != nullptr)
{
(*tor->idle_limit_hit_func)(tor, tor->idle_limit_hit_func_user_data);
}
tor->session->onIdleLimitHit(tor);
}
if (tor->isStopping)
@ -584,8 +573,6 @@ 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() };
@ -613,7 +600,7 @@ void tr_torrent::setMetainfo(tr_torrent_metainfo const& tm)
torrentInitFromInfoDict(this);
tr_peerMgrOnTorrentGotMetainfo(this);
tr_torrentFireMetadataCompleted(this);
session->onMetadataCompleted(this);
this->setDirty();
}
@ -1643,7 +1630,6 @@ void tr_torrentFree(tr_torrent* tor)
auto const lock = tor->unique_lock();
tr_torrentClearCompletenessCallback(tor);
tr_runInEventThread(session, closeTorrent, tor);
}
}
@ -1670,7 +1656,6 @@ 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);
}
@ -1707,45 +1692,6 @@ 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{};
@ -1872,7 +1818,7 @@ void tr_torrent::recheckCompleteness()
}
}
fireCompletenessChange(this, completeness, wasRunning);
this->session->onTorrentCompletenessChanged(this, completeness, wasRunning);
if (this->isDone() && wasLeeching && wasRunning)
{
@ -1891,28 +1837,6 @@ 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
**/
@ -2576,12 +2500,6 @@ 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

View File

@ -660,21 +660,6 @@ 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;

View File

@ -695,11 +695,8 @@ 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_torrentSetQueueStartCallback(tr_torrent* torrent, void (*callback)(tr_torrent*, void*), void* user_data);
void tr_sessionSetQueueStartCallback(tr_session*, void (*callback)(tr_session*, tr_torrent*, void*), void* user_data);
/***
****
@ -1185,9 +1182,9 @@ using tr_torrent_completeness_func = void (*)( //
bool wasRunning,
void* user_data);
using tr_torrent_ratio_limit_hit_func = void (*)(tr_torrent* torrent, void* user_data);
using tr_session_ratio_limit_hit_func = void (*)(tr_session*, tr_torrent* torrent, void* user_data);
using tr_torrent_idle_limit_hit_func = void (*)(tr_torrent* torrent, void* user_data);
using tr_session_idle_limit_hit_func = void (*)(tr_session*, tr_torrent* torrent, void* user_data);
/**
* Register to be notified whenever a torrent's "completeness"
@ -1202,11 +1199,9 @@ using tr_torrent_idle_limit_hit_func = void (*)(tr_torrent* torrent, void* user_
*
* @see tr_completeness
*/
void tr_torrentSetCompletenessCallback(tr_torrent* torrent, tr_torrent_completeness_func func, void* user_data);
void tr_sessionSetCompletenessCallback(tr_session* session, 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);
using tr_session_metadata_func = void (*)(tr_session* session, tr_torrent* torrent, void* user_data);
/**
* Register to be notified whenever a torrent changes from
@ -1214,25 +1209,25 @@ 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_torrentSetMetadataCallback(tr_torrent* tor, tr_torrent_metadata_func func, void* user_data);
void tr_sessionSetMetadataCallback(tr_session* session, tr_session_metadata_func func, void* user_data);
/**
* Register to be notified whenever a torrent's ratio limit
* has been hit. This will be called when the torrent's
* ul/dl ratio has met or exceeded the designated ratio limit.
*
* Has the same restrictions as tr_torrentSetCompletenessCallback
* Has the same restrictions as tr_sessionSetCompletenessCallback
*/
void tr_torrentSetRatioLimitHitCallback(tr_torrent* torrent, tr_torrent_ratio_limit_hit_func func, void* user_data);
void tr_sessionSetRatioLimitHitCallback(tr_session* torrent, tr_session_ratio_limit_hit_func func, void* user_data);
/**
* Register to be notified whenever a torrent's idle limit
* has been hit. This will be called when the seeding torrent's
* idle time has met or exceeded the designated idle limit.
*
* Has the same restrictions as tr_torrentSetCompletenessCallback
* Has the same restrictions as tr_sessionSetCompletenessCallback
*/
void tr_torrentSetIdleLimitHitCallback(tr_torrent* torrent, tr_torrent_idle_limit_hit_func func, void* user_data);
void tr_sessionSetIdleLimitHitCallback(tr_session* torrent, tr_session_idle_limit_hit_func func, void* user_data);
/**
* MANUAL ANNOUNCE

View File

@ -359,6 +359,61 @@ static void removeKeRangerRansomware()
}
}
void onStartQueue(tr_session* session, tr_torrent* tor, void* vself)
{
auto* controller = (__bridge Controller*)(vself);
auto const hashstr = @(tr_torrentView(tor).hash_string);
dispatch_async(dispatch_get_main_queue(), ^{
auto* const torrent = [controller torrentForHash:hashstr];
[torrent startQueue];
});
}
void onIdleLimitHit(tr_session* session, tr_torrent* tor, void* vself)
{
auto* const controller = (__bridge Controller*)(vself);
auto const hashstr = @(tr_torrentView(tor).hash_string);
dispatch_async(dispatch_get_main_queue(), ^{
auto* const torrent = [controller torrentForHash:hashstr];
[torrent idleLimitHit];
});
}
void onRatioLimitHit(tr_session* session, tr_torrent* tor, void* vself)
{
auto* const controller = (__bridge Controller*)(vself);
auto const hashstr = @(tr_torrentView(tor).hash_string);
dispatch_async(dispatch_get_main_queue(), ^{
auto* const torrent = [controller torrentForHash:hashstr];
[torrent ratioLimitHit];
});
}
void onMetadataCompleted(tr_session* session, tr_torrent* tor, void* vself)
{
auto* const controller = (__bridge Controller*)(vself);
auto const hashstr = @(tr_torrentView(tor).hash_string);
dispatch_async(dispatch_get_main_queue(), ^{
auto* const torrent = [controller torrentForHash:hashstr];
[torrent metadataRetrieved];
});
}
void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool wasRunning, void* vself)
{
auto* const controller = (__bridge Controller*)(vself);
auto const hashstr = @(tr_torrentView(tor).hash_string);
dispatch_async(dispatch_get_main_queue(), ^{
auto* const torrent = [controller torrentForHash:hashstr];
[torrent completenessChange:status wasRunning:wasRunning];
});
}
- (instancetype)init
{
if ((self = [super init]))
@ -514,6 +569,12 @@ static void removeKeRangerRansomware()
_fConfigDirectory = @(default_config_dir);
tr_free(default_config_dir);
tr_sessionSetIdleLimitHitCallback(_fLib, onIdleLimitHit, (__bridge void*)(self));
tr_sessionSetQueueStartCallback(_fLib, onStartQueue, (__bridge void*)(self));
tr_sessionSetRatioLimitHitCallback(_fLib, onRatioLimitHit, (__bridge void*)(self));
tr_sessionSetMetadataCallback(_fLib, onMetadataCompleted, (__bridge void*)(self));
tr_sessionSetCompletenessCallback(_fLib, onTorrentCompletenessChanged, (__bridge void*)(self));
NSApp.delegate = self;
//register for magnet URLs (has to be in init)

View File

@ -44,8 +44,13 @@ typedef NS_ENUM(unsigned int, TorrentDeterminationType) {
- (void)startTransferNoQueue;
- (void)startTransfer;
- (void)stopTransfer;
- (void)startQueue;
- (void)sleep;
- (void)wakeUp;
- (void)idleLimitHit;
- (void)ratioLimitHit;
- (void)metadataRetrieved;
- (void)completenessChange:(tr_completeness)status wasRunning:(BOOL)wasRunning;
@property(nonatomic) NSUInteger queuePosition;

View File

@ -64,7 +64,6 @@
- (void)sortFileList:(NSMutableArray<FileListNode*>*)fileNodes;
- (void)startQueue;
- (void)completenessChange:(tr_completeness)status wasRunning:(BOOL)wasRunning;
- (void)ratioLimitHit;
- (void)idleLimitHit;
- (void)metadataRetrieved;
@ -81,41 +80,6 @@
@end
void startQueueCallback(tr_torrent* torrent, void* torrentData)
{
dispatch_async(dispatch_get_main_queue(), ^{
[(__bridge Torrent*)torrentData startQueue];
});
}
void completenessChangeCallback(tr_torrent* torrent, tr_completeness status, bool wasRunning, void* torrentData)
{
dispatch_async(dispatch_get_main_queue(), ^{
[(__bridge Torrent*)torrentData completenessChange:status wasRunning:wasRunning];
});
}
void ratioLimitHitCallback(tr_torrent* torrent, void* torrentData)
{
dispatch_async(dispatch_get_main_queue(), ^{
[(__bridge Torrent*)torrentData ratioLimitHit];
});
}
void idleLimitHitCallback(tr_torrent* torrent, void* torrentData)
{
dispatch_async(dispatch_get_main_queue(), ^{
[(__bridge Torrent*)torrentData idleLimitHit];
});
}
void metadataCallback(tr_torrent* torrent, void* torrentData)
{
dispatch_async(dispatch_get_main_queue(), ^{
[(__bridge Torrent*)torrentData metadataRetrieved];
});
}
void renameCallback(tr_torrent* torrent, char const* oldPathCharString, char const* newNameCharString, int error, void* contextInfo)
{
@autoreleasepool
@ -1811,12 +1775,6 @@ bool trashDataFile(char const* filename, tr_error** error)
}
}
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;
//don't do after this point - it messes with auto-group functionality

View File

@ -74,7 +74,7 @@ TEST_P(IncompleteDirTest, incompleteDir)
{
*static_cast<tr_completeness*>(vc) = c;
};
tr_torrentSetCompletenessCallback(tor, zeroes_completeness_func, &completeness);
tr_sessionSetCompletenessCallback(session_, zeroes_completeness_func, &completeness);
struct TestIncompleteDirData
{