From: Jordan Lee Date: Fri, 14 Dec 2012 20:04:37 +0000 (+0000) Subject: (trunk, libT) #5168 'make libtransmission's public funcs nonblocking when possible... X-Git-Tag: 2.80~375 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aea6d7cd6f1426d1a16aebfd85758f6aaf60abb0;p=transmission (trunk, libT) #5168 'make libtransmission's public funcs nonblocking when possible' -- remove tr_torrentRef() and tr_torrentUnref() as discussed in https://trac.transmissionbt.com/ticket/5168#comment:8 --- diff --git a/gtk/my-valgrind.sh b/gtk/my-valgrind.sh index 146b7c02f..cd5ff98fa 100755 --- a/gtk/my-valgrind.sh +++ b/gtk/my-valgrind.sh @@ -2,5 +2,6 @@ export G_SLICE=always-malloc export G_DEBUG=gc-friendly export GLIBCXX_FORCE_NEW=1 +valgrind --tool=cachegrind ./transmission-gtk 2>&1 | tee runlog #valgrind --tool=cachegrind ./transmission-gtk -p -g /tmp/transmission-test 2>&1 | tee runlog -valgrind --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=48 --log-file=x-valgrind --show-reachable=no ./transmission-gtk -p 2>&1 | tee runlog +#valgrind --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=48 --log-file=x-valgrind --show-reachable=no ./transmission-gtk -p 2>&1 | tee runlog diff --git a/gtk/torrent-cell-renderer.c b/gtk/torrent-cell-renderer.c index 4192bb505..46f23c3e8 100644 --- a/gtk/torrent-cell-renderer.c +++ b/gtk/torrent-cell-renderer.c @@ -40,10 +40,10 @@ enum ***/ static void -getProgressString (GString * gstr, - tr_torrent * tor, - const tr_info * info, - const tr_stat * st) +getProgressString (GString * gstr, + const tr_torrent * tor, + const tr_info * info, + const tr_stat * st) { const int isDone = st->leftUntilDone == 0; const uint64_t haveTotal = st->haveUnchecked + st->haveValid; @@ -443,7 +443,7 @@ get_size_full (TorrentCellRenderer * cell, GdkPixbuf * icon; struct TorrentCellRendererPrivate * p = cell->priv; - tr_torrent * tor = p->tor; + const tr_torrent * tor = p->tor; const tr_stat * st = tr_torrentStatCached ((tr_torrent*)tor); const tr_info * inf = tr_torrentInfo (tor); GString * gstr_prog = p->gstr1; @@ -537,7 +537,7 @@ get_text_color (GtkWidget * w, const tr_stat * st, GtrColor * setme) static double -get_percent_done (tr_torrent * tor, const tr_stat * st, bool * seed) +get_percent_done (const tr_torrent * tor, const tr_stat * st, bool * seed) { double d; @@ -588,7 +588,7 @@ render_compact (TorrentCellRenderer * cell, bool seed; struct TorrentCellRendererPrivate * p = cell->priv; - tr_torrent * tor = p->tor; + const tr_torrent * tor = p->tor; const tr_stat * st = tr_torrentStatCached ((tr_torrent*)tor); const gboolean active = (st->activity != TR_STATUS_STOPPED) && (st->activity != TR_STATUS_DOWNLOAD_WAIT) && (st->activity != TR_STATUS_SEED_WAIT); const double percentDone = get_percent_done (tor, st, &seed); @@ -666,7 +666,7 @@ render_full (TorrentCellRenderer * cell, bool seed; struct TorrentCellRendererPrivate * p = cell->priv; - tr_torrent * tor = p->tor; + const tr_torrent * tor = p->tor; const tr_stat * st = tr_torrentStatCached ((tr_torrent*)tor); const tr_info * inf = tr_torrentInfo (tor); const gboolean active = (st->activity != TR_STATUS_STOPPED) && (st->activity != TR_STATUS_DOWNLOAD_WAIT) && (st->activity != TR_STATUS_SEED_WAIT); diff --git a/libtransmission/handshake.c b/libtransmission/handshake.c index c615e56f7..fa11455e9 100644 --- a/libtransmission/handshake.c +++ b/libtransmission/handshake.c @@ -1129,10 +1129,8 @@ gotError (tr_peerIo * io, tr_peerIoGetTorrentHash (io)) : NULL; /* Don't mark a peer as non-uTP unless it's really a connect failure. */ - if ((errcode == ETIMEDOUT || errcode == ECONNREFUSED) && tr_torrentRef(tor)) { + if ((errcode == ETIMEDOUT || errcode == ECONNREFUSED) && tr_isTorrent(tor)) tr_peerMgrSetUtpFailed (tor, tr_peerIoGetAddress (io, NULL), true); - tr_torrentUnref (tor); - } if (!tr_peerIoReconnect (handshake->io)) { uint8_t msg[HANDSHAKE_SIZE]; diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 84e9e5849..aad3d7f2d 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -2548,42 +2548,40 @@ tr_peerMgrOnTorrentGotMetainfo (tr_torrent * tor) } void -tr_peerMgrTorrentAvailability (tr_torrent * tor, int8_t * tab, unsigned int tabCount) +tr_peerMgrTorrentAvailability (const tr_torrent * tor, + int8_t * tab, + unsigned int tabCount) { + assert (tr_isTorrent (tor)); assert (tab != NULL); assert (tabCount > 0); - if (tr_torrentRef (tor)) + memset (tab, 0, tabCount); + + if (tr_torrentHasMetadata (tor)) { - memset (tab, 0, tabCount); + tr_piece_index_t i; + const int peerCount = tr_ptrArraySize (&tor->torrentPeers->peers); + const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase (&tor->torrentPeers->peers); + const float interval = tor->info.pieceCount / (float)tabCount; + const bool isSeed = tr_cpGetStatus (&tor->completion) == TR_SEED; - if (tr_torrentHasMetadata (tor)) + for (i=0; itorrentPeers->peers); - const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase (&tor->torrentPeers->peers); - const float interval = tor->info.pieceCount / (float)tabCount; - const bool isSeed = tr_cpGetStatus (&tor->completion) == TR_SEED; + const int piece = i * interval; - for (i=0; icompletion, piece)) { - const int piece = i * interval; - - if (isSeed || tr_cpPieceIsComplete (&tor->completion, piece)) - { - tab[i] = -1; - } - else if (peerCount) - { - int j; - for (j=0; jhave, piece)) - ++tab[i]; - } + tab[i] = -1; + } + else if (peerCount) + { + int j; + for (j=0; jhave, piece)) + ++tab[i]; } } - - tr_torrentUnref (tor); } } @@ -2648,73 +2646,74 @@ tr_peerMgrTorrentStats (tr_torrent * tor, int * setmePeersGettingFromUs, int * setmePeersFrom) { + int i; + int size; + Torrent * t; + const tr_peer ** peers; + + assert (tr_isTorrent (tor)); + *setmePeersConnected = 0; *setmePeersGettingFromUs = 0; *setmePeersSendingToUs = 0; *setmeWebseedsSendingToUs = 0; - if (tr_torrentRef (tor)) - { - int i; - const Torrent * t = tor->torrentPeers; - const int size = tr_ptrArraySize (&t->peers); - const tr_peer ** peers = (const tr_peer **) tr_ptrArrayBase (&t->peers); + t = tor->torrentPeers; + size = tr_ptrArraySize (&t->peers); + peers = (const tr_peer **) tr_ptrArrayBase (&t->peers); - for (i=0; iatom; - - if (peer->io == NULL) /* not connected */ - continue; + for (i=0; iatom; - ++*setmePeersConnected; + if (peer->io == NULL) /* not connected */ + continue; - ++setmePeersFrom[atom->fromFirst]; + ++*setmePeersConnected; - if (clientIsDownloadingFrom (tor, peer)) - ++*setmePeersSendingToUs; + ++setmePeersFrom[atom->fromFirst]; - if (clientIsUploadingTo (peer)) - ++*setmePeersGettingFromUs; - } + if (clientIsDownloadingFrom (tor, peer)) + ++*setmePeersSendingToUs; - *setmeWebseedsSendingToUs = countActiveWebseeds (t); - tr_torrentUnref (tor); + if (clientIsUploadingTo (peer)) + ++*setmePeersGettingFromUs; } + + *setmeWebseedsSendingToUs = countActiveWebseeds (t); } double* -tr_peerMgrWebSpeeds_KBps (tr_torrent * tor) +tr_peerMgrWebSpeeds_KBps (const tr_torrent * tor) { + int i; + int webseedCount; + const Torrent * t; + const tr_webseed ** webseeds; double * ret = NULL; + const uint64_t now = tr_time_msec (); - if (tr_torrentRef (tor)) - { - int i; - const Torrent * t = tor->torrentPeers; - const int webseedCount = tr_ptrArraySize (&t->webseeds); - const tr_webseed ** webseeds = (const tr_webseed**) tr_ptrArrayBase (&t->webseeds); - const uint64_t now = tr_time_msec (); + assert (tr_isTorrent (tor)); - ret = tr_new0 (double, webseedCount); + t = tor->torrentPeers; + webseedCount = tr_ptrArraySize (&t->webseeds); + webseeds = (const tr_webseed**) tr_ptrArrayBase (&t->webseeds); + ret = tr_new0 (double, webseedCount); - assert (t->manager != NULL); - assert (webseedCount == tor->info.webseedCount); - - for (i=0; imanager != NULL); + assert (webseedCount == tor->info.webseedCount); - tr_torrentUnref (tor); + for (i=0; iio ? tr_peerIoGetPieceSpeed_Bps (peer->io, now, direction) : 0.0; + return peer->io ? tr_peerIoGetPieceSpeed_Bps (peer->io, now, direction) : 0.0; } struct tr_peer_stat * -tr_peerMgrPeerStats (tr_torrent * tor, int * setmeCount) +tr_peerMgrPeerStats (const tr_torrent * tor, int * setmeCount) { + int i; int size = 0; - tr_peer_stat * ret = NULL; - - if (tr_torrentRef (tor)) - { - int i; - const Torrent * t = tor->torrentPeers; - const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase (&t->peers); - const uint64_t now_msec = tr_time_msec (); - const time_t now = tr_time (); + tr_peer_stat * ret; + const Torrent * t; + const tr_peer ** peers; + const time_t now = tr_time (); + const uint64_t now_msec = tr_time_msec (); - assert (t->manager != NULL); + assert (tr_isTorrent (tor)); + assert (tor->torrentPeers->manager != NULL); - size = tr_ptrArraySize (&t->peers); - ret = tr_new0 (tr_peer_stat, size); + t = tor->torrentPeers; + peers = (const tr_peer**) tr_ptrArrayBase (&t->peers); + size = tr_ptrArraySize (&t->peers); + ret = tr_new0 (tr_peer_stat, size); - for (i=0; iatom; - tr_peer_stat * stat = ret + i; - - tr_address_to_string_with_buf (&atom->addr, stat->addr, sizeof (stat->addr)); - tr_strlcpy (stat->client, (peer->client ? peer->client : ""), sizeof (stat->client)); - stat->port = ntohs (peer->atom->port); - stat->from = atom->fromFirst; - stat->progress = peer->progress; - stat->isUTP = peer->io->utp_socket != NULL; - stat->isEncrypted = tr_peerIoIsEncrypted (peer->io) ? 1 : 0; - stat->rateToPeer_KBps = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_CLIENT_TO_PEER)); - stat->rateToClient_KBps = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_PEER_TO_CLIENT)); - stat->peerIsChoked = peer->peerIsChoked; - stat->peerIsInterested = peer->peerIsInterested; - stat->clientIsChoked = peer->clientIsChoked; - stat->clientIsInterested = peer->clientIsInterested; - stat->isIncoming = tr_peerIoIsIncoming (peer->io); - stat->isDownloadingFrom = clientIsDownloadingFrom (tor, peer); - stat->isUploadingTo = clientIsUploadingTo (peer); - stat->isSeed = peerIsSeed (peer); - - stat->blocksToPeer = tr_historyGet (&peer->blocksSentToPeer, now, CANCEL_HISTORY_SEC); - stat->blocksToClient = tr_historyGet (&peer->blocksSentToClient, now, CANCEL_HISTORY_SEC); - stat->cancelsToPeer = tr_historyGet (&peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC); - stat->cancelsToClient = tr_historyGet (&peer->cancelsSentToClient, now, CANCEL_HISTORY_SEC); - - stat->pendingReqsToPeer = peer->pendingReqsToPeer; - stat->pendingReqsToClient = peer->pendingReqsToClient; - - pch = stat->flagStr; - if (stat->isUTP) *pch++ = 'T'; - if (t->optimistic == peer) *pch++ = 'O'; - if (stat->isDownloadingFrom) *pch++ = 'D'; - else if (stat->clientIsInterested) *pch++ = 'd'; - if (stat->isUploadingTo) *pch++ = 'U'; - else if (stat->peerIsInterested) *pch++ = 'u'; - if (!stat->clientIsChoked && !stat->clientIsInterested) *pch++ = 'K'; - if (!stat->peerIsChoked && !stat->peerIsInterested) *pch++ = '?'; - if (stat->isEncrypted) *pch++ = 'E'; - if (stat->from == TR_PEER_FROM_DHT) *pch++ = 'H'; - else if (stat->from == TR_PEER_FROM_PEX) *pch++ = 'X'; - if (stat->isIncoming) *pch++ = 'I'; - *pch = '\0'; - } - - tr_torrentUnref (tor); + for (i=0; iatom; + tr_peer_stat * stat = ret + i; + + tr_address_to_string_with_buf (&atom->addr, stat->addr, sizeof (stat->addr)); + tr_strlcpy (stat->client, (peer->client ? peer->client : ""), sizeof (stat->client)); + stat->port = ntohs (peer->atom->port); + stat->from = atom->fromFirst; + stat->progress = peer->progress; + stat->isUTP = peer->io->utp_socket != NULL; + stat->isEncrypted = tr_peerIoIsEncrypted (peer->io) ? 1 : 0; + stat->rateToPeer_KBps = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_CLIENT_TO_PEER)); + stat->rateToClient_KBps = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_PEER_TO_CLIENT)); + stat->peerIsChoked = peer->peerIsChoked; + stat->peerIsInterested = peer->peerIsInterested; + stat->clientIsChoked = peer->clientIsChoked; + stat->clientIsInterested = peer->clientIsInterested; + stat->isIncoming = tr_peerIoIsIncoming (peer->io); + stat->isDownloadingFrom = clientIsDownloadingFrom (tor, peer); + stat->isUploadingTo = clientIsUploadingTo (peer); + stat->isSeed = peerIsSeed (peer); + + stat->blocksToPeer = tr_historyGet (&peer->blocksSentToPeer, now, CANCEL_HISTORY_SEC); + stat->blocksToClient = tr_historyGet (&peer->blocksSentToClient, now, CANCEL_HISTORY_SEC); + stat->cancelsToPeer = tr_historyGet (&peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC); + stat->cancelsToClient = tr_historyGet (&peer->cancelsSentToClient, now, CANCEL_HISTORY_SEC); + + stat->pendingReqsToPeer = peer->pendingReqsToPeer; + stat->pendingReqsToClient = peer->pendingReqsToClient; + + pch = stat->flagStr; + if (stat->isUTP) *pch++ = 'T'; + if (t->optimistic == peer) *pch++ = 'O'; + if (stat->isDownloadingFrom) *pch++ = 'D'; + else if (stat->clientIsInterested) *pch++ = 'd'; + if (stat->isUploadingTo) *pch++ = 'U'; + else if (stat->peerIsInterested) *pch++ = 'u'; + if (!stat->clientIsChoked && !stat->clientIsInterested) *pch++ = 'K'; + if (!stat->peerIsChoked && !stat->peerIsInterested) *pch++ = '?'; + if (stat->isEncrypted) *pch++ = 'E'; + if (stat->from == TR_PEER_FROM_DHT) *pch++ = 'H'; + else if (stat->from == TR_PEER_FROM_PEX) *pch++ = 'X'; + if (stat->isIncoming) *pch++ = 'I'; + *pch = '\0'; } *setmeCount = size; diff --git a/libtransmission/peer-mgr.h b/libtransmission/peer-mgr.h index 0d9f3d1b4..6b88e3d5b 100644 --- a/libtransmission/peer-mgr.h +++ b/libtransmission/peer-mgr.h @@ -225,9 +225,9 @@ void tr_peerMgrAddTorrent (tr_peerMgr * manager, void tr_peerMgrRemoveTorrent (tr_torrent * tor); -void tr_peerMgrTorrentAvailability (tr_torrent * tor, - int8_t * tab, - unsigned int tabCount); +void tr_peerMgrTorrentAvailability (const tr_torrent * tor, + int8_t * tab, + unsigned int tabCount); uint64_t tr_peerMgrGetDesiredAvailable (const tr_torrent * tor); @@ -242,10 +242,10 @@ void tr_peerMgrTorrentStats (tr_torrent * tor, int * setmePeersGettingFromUs, int * setmePeersFrom); /* TR_PEER_FROM__MAX */ -struct tr_peer_stat* tr_peerMgrPeerStats (tr_torrent * tor, - int * setmeCount); +struct tr_peer_stat* tr_peerMgrPeerStats (const tr_torrent * tor, + int * setmeCount); -double* tr_peerMgrWebSpeeds_KBps (tr_torrent * tor); +double* tr_peerMgrWebSpeeds_KBps (const tr_torrent * tor); unsigned int tr_peerGetPieceSpeed_Bps (const tr_peer * peer, diff --git a/libtransmission/session.c b/libtransmission/session.c index 0ee85f30e..152c8f860 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -1769,7 +1769,7 @@ sessionCloseImpl (void * vsession) torrents[i] = tor = tr_torrentNext (session, tor); qsort (torrents, n, sizeof (tr_torrent*), compareTorrentByCur); for (i = 0; i < n; ++i) - tr_torrentUnref (torrents[i]); + tr_torrentFree (torrents[i]); tr_free (torrents); /* Close the announcer *after* closing the torrents diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index e306b3ab4..a2f817ff2 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -152,30 +152,23 @@ tr_torrentFindFromObfuscatedHash (tr_session * session, } bool -tr_torrentIsPieceTransferAllowed (tr_torrent * tor, - tr_direction direction) +tr_torrentIsPieceTransferAllowed (const tr_torrent * tor, + tr_direction direction) { - bool allowed = false; + bool allowed = true; + unsigned int limit; + assert (tr_isTorrent (tor)); assert (tr_isDirection (direction)); - if (tr_torrentRef (tor)) - { - unsigned int limit; - - allowed = true; - - if (tr_torrentUsesSpeedLimit (tor, direction)) - if (tr_torrentGetSpeedLimit_Bps (tor, direction) <= 0) - allowed = false; + if (tr_torrentUsesSpeedLimit (tor, direction)) + if (tr_torrentGetSpeedLimit_Bps (tor, direction) <= 0) + allowed = false; - if (tr_torrentUsesSessionLimits (tor)) - if (tr_sessionGetActiveSpeedLimit_Bps (tor->session, direction, &limit)) - if (limit <= 0) - allowed = false; - - tr_torrentUnref (tor); - } + if (tr_torrentUsesSessionLimits (tor)) + if (tr_sessionGetActiveSpeedLimit_Bps (tor->session, direction, &limit)) + if (limit <= 0) + allowed = false; return allowed; } @@ -208,19 +201,12 @@ tr_torrentGetSpeedLimit_Bps (const tr_torrent * tor, tr_direction dir) return tr_bandwidthGetDesiredSpeed_Bps (&tor->bandwidth, dir); } unsigned int -tr_torrentGetSpeedLimit_KBps (tr_torrent * tor, tr_direction dir) +tr_torrentGetSpeedLimit_KBps (const tr_torrent * tor, tr_direction dir) { - unsigned int limit = 0; - + assert (tr_isTorrent (tor)); assert (tr_isDirection (dir)); - if (tr_torrentRef (tor)) - { - limit = toSpeedKBps (tr_torrentGetSpeedLimit_Bps (tor, dir)); - tr_torrentUnref (tor); - } - - return limit; + return toSpeedKBps (tr_torrentGetSpeedLimit_Bps (tor, dir)); } void @@ -234,17 +220,11 @@ tr_torrentUseSpeedLimit (tr_torrent * tor, tr_direction dir, bool do_use) } bool -tr_torrentUsesSpeedLimit (tr_torrent * tor, tr_direction dir) +tr_torrentUsesSpeedLimit (const tr_torrent * tor, tr_direction dir) { - bool limited = false; - - if (tr_torrentRef (tor)) - { - limited = tr_bandwidthIsLimited (&tor->bandwidth, dir); - tr_torrentUnref (tor); - } + assert (tr_isTorrent (tor)); - return limited; + return tr_bandwidthIsLimited (&tor->bandwidth, dir); } void @@ -262,17 +242,11 @@ tr_torrentUseSessionLimits (tr_torrent * tor, bool doUse) } bool -tr_torrentUsesSessionLimits (tr_torrent * tor) +tr_torrentUsesSessionLimits (const tr_torrent * tor) { - bool limited = false; - - if (tr_torrentRef (tor)) - { - limited = tr_bandwidthAreParentLimitsHonored (&tor->bandwidth, TR_UP); - tr_torrentUnref (tor); - } + assert (tr_isTorrent (tor)); - return limited; + return tr_bandwidthAreParentLimitsHonored (&tor->bandwidth, TR_UP); } /*** @@ -315,46 +289,37 @@ tr_torrentSetRatioLimit (tr_torrent * tor, double desiredRatio) } double -tr_torrentGetRatioLimit (tr_torrent * tor) +tr_torrentGetRatioLimit (const tr_torrent * tor) { - double limit = 0; - - if (tr_torrentRef (tor)) - { - limit = tor->desiredRatio; - tr_torrentUnref (tor); - } + assert (tr_isTorrent (tor)); - return limit; + return tor->desiredRatio; } bool -tr_torrentGetSeedRatio (tr_torrent * tor, double * ratio) +tr_torrentGetSeedRatio (const tr_torrent * tor, double * ratio) { - bool isLimited = false; + bool isLimited; + + assert (tr_isTorrent (tor)); - if (tr_torrentRef (tor)) + switch (tr_torrentGetRatioMode (tor)) { - switch (tr_torrentGetRatioMode (tor)) - { - case TR_RATIOLIMIT_SINGLE: - isLimited = true; - if (ratio) - *ratio = tr_torrentGetRatioLimit (tor); - break; + case TR_RATIOLIMIT_SINGLE: + isLimited = true; + if (ratio) + *ratio = tr_torrentGetRatioLimit (tor); + break; - case TR_RATIOLIMIT_GLOBAL: - isLimited = tr_sessionIsRatioLimited (tor->session); - if (isLimited && ratio) - *ratio = tr_sessionGetRatioLimit (tor->session); - break; + case TR_RATIOLIMIT_GLOBAL: + isLimited = tr_sessionIsRatioLimited (tor->session); + if (isLimited && ratio) + *ratio = tr_sessionGetRatioLimit (tor->session); + break; - default: /* TR_RATIOLIMIT_UNLIMITED */ - isLimited = false; - break; - } - - tr_torrentUnref (tor); + default: /* TR_RATIOLIMIT_UNLIMITED */ + isLimited = false; + break; } return isLimited; @@ -363,29 +328,31 @@ tr_torrentGetSeedRatio (tr_torrent * tor, double * ratio) /* returns true if the seed ratio applies -- * it applies if the torrent's a seed AND it has a seed ratio set */ static bool -tr_torrentGetSeedRatioBytes (tr_torrent * tor, - uint64_t * setmeLeft, - uint64_t * setmeGoal) +tr_torrentGetSeedRatioBytes (const tr_torrent * tor, + uint64_t * setmeLeft, + uint64_t * setmeGoal) { - double seedRatio; - bool seedRatioApplies = false; + double seedRatio; + bool seedRatioApplies = false; + + assert (tr_isTorrent (tor)); - if (tr_torrentGetSeedRatio (tor, &seedRatio)) + if (tr_torrentGetSeedRatio (tor, &seedRatio)) { - const uint64_t u = tor->uploadedCur + tor->uploadedPrev; - const uint64_t d = tor->downloadedCur + tor->downloadedPrev; - const uint64_t baseline = d ? d : tr_cpSizeWhenDone (&tor->completion); - const uint64_t goal = baseline * seedRatio; - if (setmeLeft) *setmeLeft = goal > u ? goal - u : 0; - if (setmeGoal) *setmeGoal = goal; - seedRatioApplies = tr_torrentIsSeed (tor); + const uint64_t u = tor->uploadedCur + tor->uploadedPrev; + const uint64_t d = tor->downloadedCur + tor->downloadedPrev; + const uint64_t baseline = d ? d : tr_cpSizeWhenDone (&tor->completion); + const uint64_t goal = baseline * seedRatio; + if (setmeLeft) *setmeLeft = goal > u ? goal - u : 0; + if (setmeGoal) *setmeGoal = goal; + seedRatioApplies = tr_torrentIsSeed (tor); } - return seedRatioApplies; + return seedRatioApplies; } static bool -tr_torrentIsSeedRatioDone (tr_torrent * tor) +tr_torrentIsSeedRatioDone (const tr_torrent * tor) { uint64_t bytesLeft; return tr_torrentGetSeedRatioBytes (tor, &bytesLeft, NULL) && !bytesLeft; @@ -850,7 +817,6 @@ torrentInit (tr_torrent * tor, const tr_ctor * ctor) tor->session = session; tor->uniqueId = nextUniqueId++; tor->magicNumber = TORRENT_MAGIC_NUMBER; - tor->refCount = 1; tor->queuePosition = session->torrentCount; tr_peerIdInit (tor->peer_id); @@ -1192,25 +1158,20 @@ tr_torrentIsStalled (const tr_torrent * tor) static double -getVerifyProgress (tr_torrent * tor) +getVerifyProgress (const tr_torrent * tor) { double d = 0; - if (tr_torrentRef (tor)) + if (tr_torrentHasMetadata (tor)) { - if (tr_torrentHasMetadata (tor)) - { - tr_piece_index_t i, n; - tr_piece_index_t checked = 0; + tr_piece_index_t i, n; + tr_piece_index_t checked = 0; - for (i=0, n=tor->info.pieceCount; i!=n; ++i) - if (tor->info.pieces[i].timeChecked) - ++checked; + for (i=0, n=tor->info.pieceCount; i!=n; ++i) + if (tor->info.pieces[i].timeChecked) + ++checked; - d = checked / (double)tor->info.pieceCount; - } - - tr_torrentUnref (tor); + d = checked / (double)tor->info.pieceCount; } return d; @@ -1219,142 +1180,142 @@ getVerifyProgress (tr_torrent * tor) const tr_stat * tr_torrentStat (tr_torrent * tor) { - tr_stat * s; - uint64_t now; - uint64_t seedRatioBytesLeft; - uint64_t seedRatioBytesGoal; - bool seedRatioApplies; - uint16_t seedIdleMinutes; - - if (!tr_torrentRef(tor)) - return NULL; - - tor->lastStatTime = tr_time (); - - s = &tor->stats; - s->id = tor->uniqueId; - s->activity = tr_torrentGetActivity (tor); - s->error = tor->error; - s->queuePosition = tor->queuePosition; - s->isStalled = tr_torrentIsStalled (tor); - tr_strlcpy (s->errorString, tor->errorString, sizeof (s->errorString)); - - s->manualAnnounceTime = tr_announcerNextManualAnnounce (tor); - - tr_peerMgrTorrentStats (tor, - &s->peersConnected, - &s->webseedsSendingToUs, - &s->peersSendingToUs, - &s->peersGettingFromUs, - s->peersFrom); - - now = tr_time_msec (); - s->rawUploadSpeed_KBps = toSpeedKBps (tr_bandwidthGetRawSpeed_Bps (&tor->bandwidth, now, TR_UP)); - s->pieceUploadSpeed_KBps = toSpeedKBps (tr_bandwidthGetPieceSpeed_Bps (&tor->bandwidth, now, TR_UP)); - s->rawDownloadSpeed_KBps = toSpeedKBps (tr_bandwidthGetRawSpeed_Bps (&tor->bandwidth, now, TR_DOWN)); - s->pieceDownloadSpeed_KBps = toSpeedKBps (tr_bandwidthGetPieceSpeed_Bps (&tor->bandwidth, now, TR_DOWN)); - - s->percentComplete = tr_cpPercentComplete (&tor->completion); - s->metadataPercentComplete = tr_torrentGetMetadataPercent (tor); - - s->percentDone = tr_cpPercentDone (&tor->completion); - s->leftUntilDone = tr_cpLeftUntilDone (&tor->completion); - s->sizeWhenDone = tr_cpSizeWhenDone (&tor->completion); - s->recheckProgress = s->activity == TR_STATUS_CHECK ? getVerifyProgress (tor) : 0; - s->activityDate = tor->activityDate; - s->addedDate = tor->addedDate; - s->doneDate = tor->doneDate; - s->startDate = tor->startDate; - s->secondsSeeding = tor->secondsSeeding; - s->secondsDownloading = tor->secondsDownloading; - s->idleSecs = torrentGetIdleSecs (tor); - - s->corruptEver = tor->corruptCur + tor->corruptPrev; - s->downloadedEver = tor->downloadedCur + tor->downloadedPrev; - s->uploadedEver = tor->uploadedCur + tor->uploadedPrev; - s->haveValid = tr_cpHaveValid (&tor->completion); - s->haveUnchecked = tr_cpHaveTotal (&tor->completion) - s->haveValid; - s->desiredAvailable = tr_peerMgrGetDesiredAvailable (tor); - - s->ratio = tr_getRatio (s->uploadedEver, - s->downloadedEver ? s->downloadedEver : s->haveValid); - - seedRatioApplies = tr_torrentGetSeedRatioBytes (tor, &seedRatioBytesLeft, - &seedRatioBytesGoal); - - switch (s->activity) - { - /* etaXLSpeed exists because if we use the piece speed directly, - * brief fluctuations cause the ETA to jump all over the place. - * so, etaXLSpeed is a smoothed-out version of the piece speed - * to dampen the effect of fluctuations */ - - case TR_STATUS_DOWNLOAD: - if ((tor->etaDLSpeedCalculatedAt + 800) < now) { - tor->etaDLSpeed_KBps = ((tor->etaDLSpeedCalculatedAt + 4000) < now) - ? s->pieceDownloadSpeed_KBps /* if no recent previous speed, no need to smooth */ - : ((tor->etaDLSpeed_KBps*4.0) + s->pieceDownloadSpeed_KBps)/5.0; /* smooth across 5 readings */ - tor->etaDLSpeedCalculatedAt = now; - } + tr_stat * s; + uint64_t seedRatioBytesLeft; + uint64_t seedRatioBytesGoal; + bool seedRatioApplies; + uint16_t seedIdleMinutes; + const uint64_t now = tr_time_msec (); - if (s->leftUntilDone > s->desiredAvailable) - s->eta = TR_ETA_NOT_AVAIL; - else if (tor->etaDLSpeed_KBps < 1) - s->eta = TR_ETA_UNKNOWN; - else - s->eta = s->leftUntilDone / toSpeedBytes (tor->etaDLSpeed_KBps); + assert (tr_isTorrent (tor)); - s->etaIdle = TR_ETA_NOT_AVAIL; - break; + tor->lastStatTime = tr_time (); + + s = &tor->stats; + s->id = tor->uniqueId; + s->activity = tr_torrentGetActivity (tor); + s->error = tor->error; + s->queuePosition = tor->queuePosition; + s->isStalled = tr_torrentIsStalled (tor); + tr_strlcpy (s->errorString, tor->errorString, sizeof (s->errorString)); + + s->manualAnnounceTime = tr_announcerNextManualAnnounce (tor); + + tr_peerMgrTorrentStats (tor, + &s->peersConnected, + &s->webseedsSendingToUs, + &s->peersSendingToUs, + &s->peersGettingFromUs, + s->peersFrom); + + s->rawUploadSpeed_KBps = toSpeedKBps (tr_bandwidthGetRawSpeed_Bps (&tor->bandwidth, now, TR_UP)); + s->pieceUploadSpeed_KBps = toSpeedKBps (tr_bandwidthGetPieceSpeed_Bps (&tor->bandwidth, now, TR_UP)); + s->rawDownloadSpeed_KBps = toSpeedKBps (tr_bandwidthGetRawSpeed_Bps (&tor->bandwidth, now, TR_DOWN)); + s->pieceDownloadSpeed_KBps = toSpeedKBps (tr_bandwidthGetPieceSpeed_Bps (&tor->bandwidth, now, TR_DOWN)); + + s->percentComplete = tr_cpPercentComplete (&tor->completion); + s->metadataPercentComplete = tr_torrentGetMetadataPercent (tor); + + s->percentDone = tr_cpPercentDone (&tor->completion); + s->leftUntilDone = tr_cpLeftUntilDone (&tor->completion); + s->sizeWhenDone = tr_cpSizeWhenDone (&tor->completion); + s->recheckProgress = s->activity == TR_STATUS_CHECK ? getVerifyProgress (tor) : 0; + s->activityDate = tor->activityDate; + s->addedDate = tor->addedDate; + s->doneDate = tor->doneDate; + s->startDate = tor->startDate; + s->secondsSeeding = tor->secondsSeeding; + s->secondsDownloading = tor->secondsDownloading; + s->idleSecs = torrentGetIdleSecs (tor); + + s->corruptEver = tor->corruptCur + tor->corruptPrev; + s->downloadedEver = tor->downloadedCur + tor->downloadedPrev; + s->uploadedEver = tor->uploadedCur + tor->uploadedPrev; + s->haveValid = tr_cpHaveValid (&tor->completion); + s->haveUnchecked = tr_cpHaveTotal (&tor->completion) - s->haveValid; + s->desiredAvailable = tr_peerMgrGetDesiredAvailable (tor); + + s->ratio = tr_getRatio (s->uploadedEver, + s->downloadedEver ? s->downloadedEver : s->haveValid); + + seedRatioApplies = tr_torrentGetSeedRatioBytes (tor, &seedRatioBytesLeft, + &seedRatioBytesGoal); + + switch (s->activity) + { + /* etaXLSpeed exists because if we use the piece speed directly, + * brief fluctuations cause the ETA to jump all over the place. + * so, etaXLSpeed is a smoothed-out version of the piece speed + * to dampen the effect of fluctuations */ + case TR_STATUS_DOWNLOAD: + if ((tor->etaDLSpeedCalculatedAt + 800) < now) + { + tor->etaDLSpeed_KBps = ((tor->etaDLSpeedCalculatedAt + 4000) < now) + ? s->pieceDownloadSpeed_KBps /* if no recent previous speed, no need to smooth */ + : ((tor->etaDLSpeed_KBps*4.0) + s->pieceDownloadSpeed_KBps)/5.0; /* smooth across 5 readings */ + tor->etaDLSpeedCalculatedAt = now; + } + + if (s->leftUntilDone > s->desiredAvailable) + s->eta = TR_ETA_NOT_AVAIL; + else if (tor->etaDLSpeed_KBps < 1) + s->eta = TR_ETA_UNKNOWN; + else + s->eta = s->leftUntilDone / toSpeedBytes (tor->etaDLSpeed_KBps); - case TR_STATUS_SEED: { - if (!seedRatioApplies) - s->eta = TR_ETA_NOT_AVAIL; - else { - if ((tor->etaULSpeedCalculatedAt + 800) < now) { - tor->etaULSpeed_KBps = ((tor->etaULSpeedCalculatedAt + 4000) < now) - ? s->pieceUploadSpeed_KBps /* if no recent previous speed, no need to smooth */ - : ((tor->etaULSpeed_KBps*4.0) + s->pieceUploadSpeed_KBps)/5.0; /* smooth across 5 readings */ - tor->etaULSpeedCalculatedAt = now; - } - if (tor->etaULSpeed_KBps < 1) - s->eta = TR_ETA_UNKNOWN; - else - s->eta = seedRatioBytesLeft / toSpeedBytes (tor->etaULSpeed_KBps); - } + s->etaIdle = TR_ETA_NOT_AVAIL; + break; - if (tor->etaULSpeed_KBps < 1 && tr_torrentGetSeedIdle (tor, &seedIdleMinutes)) - s->etaIdle = seedIdleMinutes * 60 - s->idleSecs; + case TR_STATUS_SEED: + if (!seedRatioApplies) + { + s->eta = TR_ETA_NOT_AVAIL; + } + else + { + if ((tor->etaULSpeedCalculatedAt + 800) < now) + { + tor->etaULSpeed_KBps = ((tor->etaULSpeedCalculatedAt + 4000) < now) + ? s->pieceUploadSpeed_KBps /* if no recent previous speed, no need to smooth */ + : ((tor->etaULSpeed_KBps*4.0) + s->pieceUploadSpeed_KBps)/5.0; /* smooth across 5 readings */ + tor->etaULSpeedCalculatedAt = now; + } + + if (tor->etaULSpeed_KBps < 1) + s->eta = TR_ETA_UNKNOWN; else - s->etaIdle = TR_ETA_NOT_AVAIL; - break; - } + s->eta = seedRatioBytesLeft / toSpeedBytes (tor->etaULSpeed_KBps); + } - default: - s->eta = TR_ETA_NOT_AVAIL; - s->etaIdle = TR_ETA_NOT_AVAIL; - break; - } + if (tor->etaULSpeed_KBps < 1 && tr_torrentGetSeedIdle (tor, &seedIdleMinutes)) + s->etaIdle = seedIdleMinutes * 60 - s->idleSecs; + else + s->etaIdle = TR_ETA_NOT_AVAIL; + break; - /* s->haveValid is here to make sure a torrent isn't marked 'finished' - * when the user hits "uncheck all" prior to starting the torrent... */ - s->finished = tor->finishedSeedingByIdle || (seedRatioApplies && !seedRatioBytesLeft && s->haveValid); + default: + s->eta = TR_ETA_NOT_AVAIL; + s->etaIdle = TR_ETA_NOT_AVAIL; + break; + } - if (!seedRatioApplies || s->finished) - s->seedRatioPercentDone = 1; - else if (!seedRatioBytesGoal) /* impossible? safeguard for div by zero */ - s->seedRatioPercentDone = 0; - else - s->seedRatioPercentDone = (double)(seedRatioBytesGoal - seedRatioBytesLeft) / seedRatioBytesGoal; + /* s->haveValid is here to make sure a torrent isn't marked 'finished' + * when the user hits "uncheck all" prior to starting the torrent... */ + s->finished = tor->finishedSeedingByIdle || (seedRatioApplies && !seedRatioBytesLeft && s->haveValid); - /* test some of the constraints */ - assert (s->sizeWhenDone <= tor->info.totalSize); - assert (s->leftUntilDone <= s->sizeWhenDone); - assert (s->desiredAvailable <= s->leftUntilDone); + if (!seedRatioApplies || s->finished) + s->seedRatioPercentDone = 1; + else if (!seedRatioBytesGoal) /* impossible? safeguard for div by zero */ + s->seedRatioPercentDone = 0; + else + s->seedRatioPercentDone = (double)(seedRatioBytesGoal - seedRatioBytesLeft) / seedRatioBytesGoal; - tr_torrentUnref (tor); + /* test some of the constraints */ + assert (s->sizeWhenDone <= tor->info.totalSize); + assert (s->leftUntilDone <= s->sizeWhenDone); + assert (s->desiredAvailable <= s->leftUntilDone); - return s; + return s; } /*** @@ -1436,31 +1397,19 @@ tr_torrentFilesFree (tr_file_stat * files, ***/ double* -tr_torrentWebSpeeds_KBps (tr_torrent * tor) +tr_torrentWebSpeeds_KBps (const tr_torrent * tor) { - double * ret = NULL; - - if (tr_torrentRef (tor)) - { - ret = tr_peerMgrWebSpeeds_KBps (tor); - tr_torrentUnref (tor); - } + assert (tr_isTorrent (tor)); - return ret; + return tr_peerMgrWebSpeeds_KBps (tor); } tr_peer_stat * -tr_torrentPeers (tr_torrent * tor, int * peerCount) +tr_torrentPeers (const tr_torrent * tor, int * peerCount) { - tr_peer_stat * ret = NULL; - - if (tr_torrentRef (tor)) - { - ret = tr_peerMgrPeerStats (tor, peerCount); - tr_torrentUnref (tor); - } + assert (tr_isTorrent (tor)); - return ret; + return tr_peerMgrPeerStats (tor, peerCount); } void @@ -1470,43 +1419,32 @@ tr_torrentPeersFree (tr_peer_stat * peers, int peerCount UNUSED) } tr_tracker_stat * -tr_torrentTrackers (tr_torrent * torrent, int * setmeTrackerCount) +tr_torrentTrackers (const tr_torrent * tor, int * setmeTrackerCount) { - tr_tracker_stat * ret = NULL; - - if (tr_torrentRef (torrent)) - { - ret = tr_announcerStats (torrent, setmeTrackerCount); - tr_torrentUnref (torrent); - } + assert (tr_isTorrent (tor)); - return ret; + return tr_announcerStats (tor, setmeTrackerCount); } void tr_torrentTrackersFree (tr_tracker_stat * trackers, int trackerCount) { - tr_announcerStatsFree (trackers, trackerCount); + tr_announcerStatsFree (trackers, trackerCount); } void -tr_torrentAvailability (tr_torrent * tor, int8_t * tab, int size) +tr_torrentAvailability (const tr_torrent * tor, int8_t * tab, int size) { - if ((tab != NULL) && (size > 0) && tr_torrentRef (tor)) - { - tr_peerMgrTorrentAvailability (tor, tab, size); - tr_torrentUnref (tor); - } + assert (tr_isTorrent (tor)); + + if ((tab != NULL) && (size > 0)) + tr_peerMgrTorrentAvailability (tor, tab, size); } void -tr_torrentAmountFinished (tr_torrent * tor, float * tab, int size) +tr_torrentAmountFinished (const tr_torrent * tor, float * tab, int size) { - if (tr_torrentRef (tor)) - { - tr_cpGetAmountDone (&tor->completion, tab, size); - tr_torrentUnref (tor); - } + tr_cpGetAmountDone (&tor->completion, tab, size); } static void @@ -1812,21 +1750,22 @@ stopTorrent (void * vtor) tr_torrent * tor = vtor; tr_torinf (tor, "%s", "Pausing"); - if (tr_torrentLock (tor)) - { - tr_verifyRemove (tor); - torrentSetQueued (tor, false); - tr_peerMgrStopTorrent (tor); - tr_announcerTorrentStopped (tor); - tr_cacheFlushTorrent (tor->session->cache, tor); + assert (tr_isTorrent (tor)); - tr_fdTorrentClose (tor->session, tor->uniqueId); + tr_torrentLock (tor); - if (!tor->isDeleting) - tr_torrentSave (tor); + tr_verifyRemove (tor); + torrentSetQueued (tor, false); + tr_peerMgrStopTorrent (tor); + tr_announcerTorrentStopped (tor); + tr_cacheFlushTorrent (tor->session->cache, tor); - tr_torrentUnlock (tor); - } + tr_fdTorrentClose (tor->session, tor->uniqueId); + + if (!tor->isDeleting) + tr_torrentSave (tor); + + tr_torrentUnlock (tor); } void @@ -1874,45 +1813,19 @@ closeTorrent (void * vtor) } void -tr_torrentUnref (tr_torrent * tor) +tr_torrentFree (tr_torrent * tor) { - assert (tr_isTorrent (tor)); + if (tr_isTorrent (tor)) + { + tr_session * session = tor->session; + assert (tr_isSession (session)); + tr_sessionLock (session); - if (tor->refCount > 1) - { - --tor->refCount; - } - else if (tor->refCount == 1) - { - tr_session * session = tor->session; - - tr_sessionLock (session); - tr_torrentClearCompletenessCallback (tor); - tr_runInEventThread (session, closeTorrent, tor); - tr_sessionUnlock (session); + tr_torrentClearCompletenessCallback (tor); + tr_runInEventThread (session, closeTorrent, tor); - --tor->refCount; - } -} - -bool -tr_torrentLock (const tr_torrent * tor) -{ - if (!tr_isTorrent (tor)) - return false; - - tr_sessionLock (tor->session); - return true; -} - -bool -tr_torrentRef (tr_torrent * tor) -{ - if (!tr_isTorrent (tor)) - return false; - - ++tor->refCount; - return true; + tr_sessionUnlock (session); + } } struct remove_data @@ -2096,55 +2009,55 @@ torrentCallScript (const tr_torrent * tor, const char * script) void tr_torrentRecheckCompleteness (tr_torrent * tor) { - if (tr_torrentLock (tor)) - { - const tr_completeness completeness = tr_cpGetStatus (&tor->completion); - - if (completeness != tor->completeness) - { - const int recentChange = tor->downloadedCur != 0; - const bool wasLeeching = !tr_torrentIsSeed (tor); - const bool wasRunning = tor->isRunning; + tr_completeness completeness; - if (recentChange) - tr_torinf (tor, _("State changed from \"%1$s\" to \"%2$s\""), - getCompletionString (tor->completeness), - getCompletionString (completeness)); + tr_torrentLock (tor); - tor->completeness = completeness; - tr_fdTorrentClose (tor->session, tor->uniqueId); + completeness = tr_cpGetStatus (&tor->completion); + if (completeness != tor->completeness) + { + const int recentChange = tor->downloadedCur != 0; + const bool wasLeeching = !tr_torrentIsSeed (tor); + const bool wasRunning = tor->isRunning; - fireCompletenessChange (tor, completeness, wasRunning); + if (recentChange) + tr_torinf (tor, _("State changed from \"%1$s\" to \"%2$s\""), + getCompletionString (tor->completeness), + getCompletionString (completeness)); - if (tr_torrentIsSeed (tor)) - { - if (recentChange) - { - tr_announcerTorrentCompleted (tor); - tor->doneDate = tor->anyDate = tr_time (); - } + tor->completeness = completeness; + tr_fdTorrentClose (tor->session, tor->uniqueId); - if (wasLeeching && wasRunning) - { - /* clear interested flag on all peers */ - tr_peerMgrClearInterest (tor); + fireCompletenessChange (tor, completeness, wasRunning); - /* if completeness was TR_LEECH then the seed limit check will have been skipped in bandwidthPulse */ - tr_torrentCheckSeedLimit (tor); - } + if (tr_torrentIsSeed (tor)) + { + if (recentChange) + { + tr_announcerTorrentCompleted (tor); + tor->doneDate = tor->anyDate = tr_time (); + } - if (tor->currentDir == tor->incompleteDir) - tr_torrentSetLocation (tor, tor->downloadDir, true, NULL, NULL); + if (wasLeeching && wasRunning) + { + /* clear interested flag on all peers */ + tr_peerMgrClearInterest (tor); - if (tr_sessionIsTorrentDoneScriptEnabled (tor->session)) - torrentCallScript (tor, tr_sessionGetTorrentDoneScript (tor->session)); + /* if completeness was TR_LEECH then the seed limit check will have been skipped in bandwidthPulse */ + tr_torrentCheckSeedLimit (tor); } - tr_torrentSetDirty (tor); + if (tor->currentDir == tor->incompleteDir) + tr_torrentSetLocation (tor, tor->downloadDir, true, NULL, NULL); + + if (tr_sessionIsTorrentDoneScriptEnabled (tor->session)) + torrentCallScript (tor, tr_sessionGetTorrentDoneScript (tor->session)); } - tr_torrentUnlock (tor); + tr_torrentSetDirty (tor); } + + tr_torrentUnlock (tor); } /*** @@ -2214,20 +2127,17 @@ tr_torrentSetFilePriorities (tr_torrent * tor, } tr_priority_t* -tr_torrentGetFilePriorities (tr_torrent * tor) +tr_torrentGetFilePriorities (const tr_torrent * tor) { tr_file_index_t i; - tr_priority_t * p = NULL; + tr_priority_t * p; - if (tr_torrentRef (tor)) - { - p = tr_new0 (tr_priority_t, tor->info.fileCount); + assert (tr_isTorrent (tor)); - for (i=0; iinfo.fileCount; ++i) - p[i] = tor->info.files[i].priority; + p = tr_new0 (tr_priority_t, tor->info.fileCount); - tr_torrentUnref (tor); - } + for (i=0; iinfo.fileCount; ++i) + p[i] = tor->info.files[i].priority; return p; } diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index bf6d3695f..01b73d3b3 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -29,6 +29,8 @@ struct tr_magnet_info; *** Package-visible ctor API **/ +void tr_torrentFree (tr_torrent * tor); + void tr_ctorSetSave (tr_ctor * ctor, bool saveMetadataInOurTorrentsDir); @@ -62,8 +64,8 @@ tr_torrent* tr_torrentFindFromHashString (tr_session * session, tr_torrent* tr_torrentFindFromObfuscatedHash (tr_session * session, const uint8_t * hash); -bool tr_torrentIsPieceTransferAllowed (tr_torrent * torrent, - tr_direction direction); +bool tr_torrentIsPieceTransferAllowed (const tr_torrent * torrent, + tr_direction direction); @@ -139,8 +141,6 @@ struct tr_torrent int magicNumber; - size_t refCount; - tr_stat_errtype error; char errorString[128]; char errorTracker[128]; @@ -302,16 +302,17 @@ tr_torBlockCountBytes (const tr_torrent * tor, const tr_block_index_t block) : tor->blockSize; } -bool tr_torrentLock (const tr_torrent * tor); - +static inline void tr_torrentLock (const tr_torrent * tor) +{ + tr_sessionLock (tor->session); +} static inline bool tr_torrentIsLocked (const tr_torrent * tor) { - return tr_sessionIsLocked (tor->session); + return tr_sessionIsLocked (tor->session); } - static inline void tr_torrentUnlock (const tr_torrent * tor) { - tr_sessionUnlock (tor->session); + tr_sessionUnlock (tor->session); } static inline bool @@ -365,7 +366,6 @@ static inline bool tr_isTorrent (const tr_torrent * tor) { return (tor != NULL) && (tor->magicNumber == TORRENT_MAGIC_NUMBER) - && (tor->refCount > 0) && (tr_isSession (tor->session)); } diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index ad8705da0..1ea57c24f 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -1145,26 +1145,9 @@ tr_torrent * tr_torrentNew (const tr_ctor * ctor, /** @addtogroup tr_torrent Torrents @{ */ -/** - * @brief Decrements a torrent's refcount. - * - * If its refcount becomes zero, the torrent is stopped and its memory is freed. - */ -void tr_torrentUnref (tr_torrent * torrent); - -/** - * @brief Increments a torrent's refcount. - * - * @return true if the pointer is a live torrent object. - * This is a convenience for validity checking before use: - * if (tr_torrentRef (tor)) { foo(); bar(); tr_torrentUnref(tor); } - */ -bool tr_torrentRef (tr_torrent * torrent); - typedef int tr_fileFunc (const char * filename); -/** @brief Removes our .torrent and .resume files for - this torrent, then calls tr_torrentFree (). */ +/** @brief Removes our .torrent and .resume files for this torrent */ void tr_torrentRemove (tr_torrent * torrent, bool removeLocalData, tr_fileFunc removeFunc); @@ -1238,13 +1221,13 @@ char* tr_torrentFindFile (const tr_torrent * tor, tr_file_index_t fileNo); ***/ void tr_torrentSetSpeedLimit_KBps (tr_torrent *, tr_direction, unsigned int KBps); -unsigned int tr_torrentGetSpeedLimit_KBps (tr_torrent *, tr_direction); +unsigned int tr_torrentGetSpeedLimit_KBps (const tr_torrent *, tr_direction); void tr_torrentUseSpeedLimit (tr_torrent *, tr_direction, bool); -bool tr_torrentUsesSpeedLimit (tr_torrent *, tr_direction); +bool tr_torrentUsesSpeedLimit (const tr_torrent *, tr_direction); void tr_torrentUseSessionLimits (tr_torrent *, bool); -bool tr_torrentUsesSessionLimits (tr_torrent *); +bool tr_torrentUsesSessionLimits (const tr_torrent *); /**** @@ -1272,10 +1255,10 @@ tr_ratiolimit tr_torrentGetRatioMode (const tr_torrent * tor); void tr_torrentSetRatioLimit (tr_torrent * tor, double ratio); -double tr_torrentGetRatioLimit (tr_torrent * tor); +double tr_torrentGetRatioLimit (const tr_torrent * tor); -bool tr_torrentGetSeedRatio (tr_torrent *, double * ratio); +bool tr_torrentGetSeedRatio (const tr_torrent *, double * ratio); /**** @@ -1344,7 +1327,7 @@ void tr_torrentSetFilePriorities (tr_torrent * torrent, * each holding a TR_PRI_NORMAL, TR_PRI_HIGH, or TR_PRI_LOW. * It's the caller's responsibility to free () this. */ -tr_priority_t* tr_torrentGetFilePriorities (tr_torrent * torrent); +tr_priority_t* tr_torrentGetFilePriorities (const tr_torrent * torrent); /** @brief Set a batch of files to be downloaded or not. */ void tr_torrentSetFileDLs (tr_torrent * torrent, @@ -1579,8 +1562,8 @@ typedef struct tr_peer_stat } tr_peer_stat; -tr_peer_stat * tr_torrentPeers (tr_torrent * torrent, - int * peerCount); +tr_peer_stat * tr_torrentPeers (const tr_torrent * torrent, + int * peerCount); void tr_torrentPeersFree (tr_peer_stat * peerStats, int peerCount); @@ -1702,8 +1685,8 @@ typedef struct } tr_tracker_stat; -tr_tracker_stat * tr_torrentTrackers (tr_torrent * torrent, - int * setmeTrackerCount); +tr_tracker_stat * tr_torrentTrackers (const tr_torrent * torrent, + int * setmeTrackerCount); void tr_torrentTrackersFree (tr_tracker_stat * trackerStats, int trackerCount); @@ -1720,7 +1703,7 @@ void tr_torrentTrackersFree (tr_tracker_stat * trackerStats, * return -1 instead of 0 KiB/s. * NOTE: always free this array with tr_free () when you're done with it. */ -double* tr_torrentWebSpeeds_KBps (tr_torrent * torrent); +double* tr_torrentWebSpeeds_KBps (const tr_torrent * torrent); typedef struct tr_file_stat { @@ -1744,13 +1727,13 @@ void tr_torrentFilesFree (tr_file_stat * files, * to either -1 if we have the piece, otherwise it is set to the number * of connected peers who have the piece. **********************************************************************/ -void tr_torrentAvailability (tr_torrent * torrent, - int8_t * tab, - int size); +void tr_torrentAvailability (const tr_torrent * torrent, + int8_t * tab, + int size); -void tr_torrentAmountFinished (tr_torrent * torrent, - float * tab, - int size); +void tr_torrentAmountFinished (const tr_torrent * torrent, + float * tab, + int size); void tr_torrentVerify (tr_torrent * torrent);