Changeset 13670


Ignore:
Timestamp:
Dec 14, 2012, 8:04:37 PM (8 years ago)
Author:
jordan
Message:

(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

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/my-valgrind.sh

    r13560 r13670  
    33export G_DEBUG=gc-friendly
    44export GLIBCXX_FORCE_NEW=1
     5valgrind --tool=cachegrind ./transmission-gtk 2>&1 | tee runlog
    56#valgrind --tool=cachegrind ./transmission-gtk -p -g /tmp/transmission-test 2>&1 | tee runlog
    6 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
     7#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
  • trunk/gtk/torrent-cell-renderer.c

    r13651 r13670  
    4141
    4242static void
    43 getProgressString (GString        * gstr,
    44                    tr_torrent    * tor,
    45                    const tr_info  * info,
    46                    const tr_stat  * st)
     43getProgressString (GString          * gstr,
     44                   const tr_torrent * tor,
     45                   const tr_info    * info,
     46                   const tr_stat    * st)
    4747{
    4848    const int      isDone = st->leftUntilDone == 0;
     
    444444
    445445    struct TorrentCellRendererPrivate * p = cell->priv;
    446     tr_torrent * tor = p->tor;
     446    const tr_torrent * tor = p->tor;
    447447    const tr_stat * st = tr_torrentStatCached ((tr_torrent*)tor);
    448448    const tr_info * inf = tr_torrentInfo (tor);
     
    538538
    539539static double
    540 get_percent_done (tr_torrent * tor, const tr_stat * st, bool * seed)
     540get_percent_done (const tr_torrent * tor, const tr_stat * st, bool * seed)
    541541{
    542542  double d;
     
    589589
    590590    struct TorrentCellRendererPrivate * p = cell->priv;
    591     tr_torrent * tor = p->tor;
     591    const tr_torrent * tor = p->tor;
    592592    const tr_stat * st = tr_torrentStatCached ((tr_torrent*)tor);
    593593    const gboolean active = (st->activity != TR_STATUS_STOPPED) && (st->activity != TR_STATUS_DOWNLOAD_WAIT) && (st->activity != TR_STATUS_SEED_WAIT);
     
    667667
    668668    struct TorrentCellRendererPrivate * p = cell->priv;
    669     tr_torrent * tor = p->tor;
     669    const tr_torrent * tor = p->tor;
    670670    const tr_stat * st = tr_torrentStatCached ((tr_torrent*)tor);
    671671    const tr_info * inf = tr_torrentInfo (tor);
  • trunk/libtransmission/handshake.c

    r13651 r13670  
    11301130            NULL;
    11311131        /* Don't mark a peer as non-uTP unless it's really a connect failure. */
    1132         if ((errcode == ETIMEDOUT || errcode == ECONNREFUSED) && tr_torrentRef(tor)) {
     1132        if ((errcode == ETIMEDOUT || errcode == ECONNREFUSED) && tr_isTorrent(tor))
    11331133            tr_peerMgrSetUtpFailed (tor, tr_peerIoGetAddress (io, NULL), true);
    1134             tr_torrentUnref (tor);
    1135         }
    11361134
    11371135        if (!tr_peerIoReconnect (handshake->io)) {
  • trunk/libtransmission/peer-mgr.c

    r13652 r13670  
    25492549
    25502550void
    2551 tr_peerMgrTorrentAvailability (tr_torrent * tor, int8_t * tab, unsigned int tabCount)
    2552 {
     2551tr_peerMgrTorrentAvailability (const tr_torrent  * tor,
     2552                               int8_t            * tab,
     2553                               unsigned int        tabCount)
     2554{
     2555  assert (tr_isTorrent (tor));
    25532556  assert (tab != NULL);
    25542557  assert (tabCount > 0);
    25552558
    2556   if (tr_torrentRef (tor))
    2557     {
    2558       memset (tab, 0, tabCount);
    2559 
    2560       if (tr_torrentHasMetadata (tor))
     2559  memset (tab, 0, tabCount);
     2560
     2561  if (tr_torrentHasMetadata (tor))
     2562    {
     2563      tr_piece_index_t i;
     2564      const int peerCount = tr_ptrArraySize (&tor->torrentPeers->peers);
     2565      const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase (&tor->torrentPeers->peers);
     2566      const float interval = tor->info.pieceCount / (float)tabCount;
     2567      const bool isSeed = tr_cpGetStatus (&tor->completion) == TR_SEED;
     2568
     2569      for (i=0; i<tabCount; ++i)
    25612570        {
    2562           tr_piece_index_t i;
    2563           const int peerCount = tr_ptrArraySize (&tor->torrentPeers->peers);
    2564           const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase (&tor->torrentPeers->peers);
    2565           const float interval = tor->info.pieceCount / (float)tabCount;
    2566           const bool isSeed = tr_cpGetStatus (&tor->completion) == TR_SEED;
    2567 
    2568           for (i=0; i<tabCount; ++i)
     2571          const int piece = i * interval;
     2572
     2573          if (isSeed || tr_cpPieceIsComplete (&tor->completion, piece))
    25692574            {
    2570               const int piece = i * interval;
    2571 
    2572               if (isSeed || tr_cpPieceIsComplete (&tor->completion, piece))
    2573                 {
    2574                   tab[i] = -1;
    2575                 }
    2576               else if (peerCount)
    2577                 {
    2578                   int j;
    2579                   for (j=0; j<peerCount; ++j)
    2580                     if (tr_bitfieldHas (&peers[j]->have, piece))
    2581                       ++tab[i];
    2582                 }
     2575              tab[i] = -1;
     2576            }
     2577          else if (peerCount)
     2578            {
     2579              int j;
     2580              for (j=0; j<peerCount; ++j)
     2581                if (tr_bitfieldHas (&peers[j]->have, piece))
     2582                  ++tab[i];
    25832583            }
    25842584        }
    2585 
    2586       tr_torrentUnref (tor);
    25872585    }
    25882586}
     
    26492647                        int         * setmePeersFrom)
    26502648{
     2649  int i;
     2650  int size;
     2651  Torrent * t;
     2652  const tr_peer ** peers;
     2653
     2654  assert (tr_isTorrent (tor));
     2655
    26512656  *setmePeersConnected       = 0;
    26522657  *setmePeersGettingFromUs   = 0;
     
    26542659  *setmeWebseedsSendingToUs  = 0;
    26552660
    2656   if (tr_torrentRef (tor))
    2657     {
    2658       int i;
    2659       const Torrent * t = tor->torrentPeers;
    2660       const int size = tr_ptrArraySize (&t->peers);
    2661       const tr_peer ** peers = (const tr_peer **) tr_ptrArrayBase (&t->peers);
    2662 
    2663       for (i=0; i<TR_PEER_FROM__MAX; ++i)
    2664         setmePeersFrom[i] = 0;
    2665 
    2666       for (i=0; i<size; ++i)
    2667         {
    2668           const tr_peer * peer = peers[i];
    2669           const struct peer_atom * atom = peer->atom;
    2670 
    2671           if (peer->io == NULL) /* not connected */
    2672             continue;
    2673 
    2674           ++*setmePeersConnected;
    2675 
    2676           ++setmePeersFrom[atom->fromFirst];
    2677 
    2678           if (clientIsDownloadingFrom (tor, peer))
    2679             ++*setmePeersSendingToUs;
    2680 
    2681           if (clientIsUploadingTo (peer))
    2682             ++*setmePeersGettingFromUs;
    2683         }
    2684 
    2685       *setmeWebseedsSendingToUs = countActiveWebseeds (t);
    2686       tr_torrentUnref (tor);
    2687     }
     2661  t = tor->torrentPeers;
     2662  size = tr_ptrArraySize (&t->peers);
     2663  peers = (const tr_peer **) tr_ptrArrayBase (&t->peers);
     2664
     2665  for (i=0; i<TR_PEER_FROM__MAX; ++i)
     2666    setmePeersFrom[i] = 0;
     2667
     2668  for (i=0; i<size; ++i)
     2669    {
     2670      const tr_peer * peer = peers[i];
     2671      const struct peer_atom * atom = peer->atom;
     2672
     2673      if (peer->io == NULL) /* not connected */
     2674        continue;
     2675
     2676      ++*setmePeersConnected;
     2677
     2678      ++setmePeersFrom[atom->fromFirst];
     2679
     2680      if (clientIsDownloadingFrom (tor, peer))
     2681        ++*setmePeersSendingToUs;
     2682
     2683      if (clientIsUploadingTo (peer))
     2684        ++*setmePeersGettingFromUs;
     2685    }
     2686
     2687  *setmeWebseedsSendingToUs = countActiveWebseeds (t);
    26882688}
    26892689
    26902690double*
    2691 tr_peerMgrWebSpeeds_KBps (tr_torrent * tor)
    2692 {
     2691tr_peerMgrWebSpeeds_KBps (const tr_torrent * tor)
     2692{
     2693  int i;
     2694  int webseedCount;
     2695  const Torrent * t;
     2696  const tr_webseed ** webseeds;
    26932697  double * ret = NULL;
    2694 
    2695   if (tr_torrentRef (tor))
    2696     {
    2697       int i;
    2698       const Torrent * t = tor->torrentPeers;
    2699       const int webseedCount = tr_ptrArraySize (&t->webseeds);
    2700       const tr_webseed ** webseeds = (const tr_webseed**) tr_ptrArrayBase (&t->webseeds);
    2701       const uint64_t now = tr_time_msec ();
    2702 
    2703       ret = tr_new0 (double, webseedCount);
    2704 
    2705       assert (t->manager != NULL);
    2706       assert (webseedCount == tor->info.webseedCount);
    2707 
    2708       for (i=0; i<webseedCount; ++i)
    2709         {
    2710           unsigned int Bps;
    2711           if (tr_webseedGetSpeed_Bps (webseeds[i], now, &Bps))
    2712             ret[i] = Bps / (double)tr_speed_K;
    2713           else
    2714             ret[i] = -1.0;
    2715         }
    2716 
    2717       tr_torrentUnref (tor);
     2698  const uint64_t now = tr_time_msec ();
     2699
     2700  assert (tr_isTorrent (tor));
     2701
     2702  t = tor->torrentPeers;
     2703  webseedCount = tr_ptrArraySize (&t->webseeds);
     2704  webseeds = (const tr_webseed**) tr_ptrArrayBase (&t->webseeds);
     2705  ret = tr_new0 (double, webseedCount);
     2706
     2707  assert (t->manager != NULL);
     2708  assert (webseedCount == tor->info.webseedCount);
     2709
     2710  for (i=0; i<webseedCount; ++i)
     2711    {
     2712      unsigned int Bps;
     2713      if (tr_webseedGetSpeed_Bps (webseeds[i], now, &Bps))
     2714        ret[i] = Bps / (double)tr_speed_K;
     2715      else
     2716        ret[i] = -1.0;
    27182717    }
    27192718
     
    27242723tr_peerGetPieceSpeed_Bps (const tr_peer * peer, uint64_t now, tr_direction direction)
    27252724{
    2726     return peer->io ? tr_peerIoGetPieceSpeed_Bps (peer->io, now, direction) : 0.0;
     2725  return peer->io ? tr_peerIoGetPieceSpeed_Bps (peer->io, now, direction) : 0.0;
    27272726}
    27282727
    27292728struct tr_peer_stat *
    2730 tr_peerMgrPeerStats (tr_torrent * tor, int * setmeCount)
    2731 {
     2729tr_peerMgrPeerStats (const tr_torrent * tor, int * setmeCount)
     2730{
     2731  int i;
    27322732  int size = 0;
    2733   tr_peer_stat * ret = NULL;
    2734 
    2735   if (tr_torrentRef (tor))
    2736     {
    2737       int i;
    2738       const Torrent * t = tor->torrentPeers;
    2739       const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase (&t->peers);
    2740       const uint64_t now_msec = tr_time_msec ();
    2741       const time_t now = tr_time ();
    2742 
    2743       assert (t->manager != NULL);
    2744 
    2745       size = tr_ptrArraySize (&t->peers);
    2746       ret = tr_new0 (tr_peer_stat, size);
    2747 
    2748       for (i=0; i<size; ++i)
    2749         {
    2750           char *                   pch;
    2751           const tr_peer *          peer = peers[i];
    2752           const struct peer_atom * atom = peer->atom;
    2753           tr_peer_stat *           stat = ret + i;
    2754 
    2755           tr_address_to_string_with_buf (&atom->addr, stat->addr, sizeof (stat->addr));
    2756           tr_strlcpy (stat->client, (peer->client ? peer->client : ""), sizeof (stat->client));
    2757           stat->port                = ntohs (peer->atom->port);
    2758           stat->from                = atom->fromFirst;
    2759           stat->progress            = peer->progress;
    2760           stat->isUTP               = peer->io->utp_socket != NULL;
    2761           stat->isEncrypted         = tr_peerIoIsEncrypted (peer->io) ? 1 : 0;
    2762           stat->rateToPeer_KBps     = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_CLIENT_TO_PEER));
    2763           stat->rateToClient_KBps   = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_PEER_TO_CLIENT));
    2764           stat->peerIsChoked        = peer->peerIsChoked;
    2765           stat->peerIsInterested    = peer->peerIsInterested;
    2766           stat->clientIsChoked      = peer->clientIsChoked;
    2767           stat->clientIsInterested  = peer->clientIsInterested;
    2768           stat->isIncoming          = tr_peerIoIsIncoming (peer->io);
    2769           stat->isDownloadingFrom   = clientIsDownloadingFrom (tor, peer);
    2770           stat->isUploadingTo       = clientIsUploadingTo (peer);
    2771           stat->isSeed              = peerIsSeed (peer);
    2772 
    2773           stat->blocksToPeer        = tr_historyGet (&peer->blocksSentToPeer,    now, CANCEL_HISTORY_SEC);
    2774           stat->blocksToClient      = tr_historyGet (&peer->blocksSentToClient,  now, CANCEL_HISTORY_SEC);
    2775           stat->cancelsToPeer       = tr_historyGet (&peer->cancelsSentToPeer,   now, CANCEL_HISTORY_SEC);
    2776           stat->cancelsToClient     = tr_historyGet (&peer->cancelsSentToClient, now, CANCEL_HISTORY_SEC);
    2777 
    2778           stat->pendingReqsToPeer   = peer->pendingReqsToPeer;
    2779           stat->pendingReqsToClient = peer->pendingReqsToClient;
    2780 
    2781           pch = stat->flagStr;
    2782           if (stat->isUTP) *pch++ = 'T';
    2783           if (t->optimistic == peer) *pch++ = 'O';
    2784           if (stat->isDownloadingFrom) *pch++ = 'D';
    2785           else if (stat->clientIsInterested) *pch++ = 'd';
    2786           if (stat->isUploadingTo) *pch++ = 'U';
    2787           else if (stat->peerIsInterested) *pch++ = 'u';
    2788           if (!stat->clientIsChoked && !stat->clientIsInterested) *pch++ = 'K';
    2789           if (!stat->peerIsChoked && !stat->peerIsInterested) *pch++ = '?';
    2790           if (stat->isEncrypted) *pch++ = 'E';
    2791           if (stat->from == TR_PEER_FROM_DHT) *pch++ = 'H';
    2792           else if (stat->from == TR_PEER_FROM_PEX) *pch++ = 'X';
    2793           if (stat->isIncoming) *pch++ = 'I';
    2794           *pch = '\0';
    2795         }
    2796 
    2797       tr_torrentUnref (tor);
     2733  tr_peer_stat * ret;
     2734  const Torrent * t;
     2735  const tr_peer ** peers;
     2736  const time_t now = tr_time ();
     2737  const uint64_t now_msec = tr_time_msec ();
     2738
     2739  assert (tr_isTorrent (tor));
     2740  assert (tor->torrentPeers->manager != NULL);
     2741
     2742  t = tor->torrentPeers;
     2743  peers = (const tr_peer**) tr_ptrArrayBase (&t->peers);
     2744  size = tr_ptrArraySize (&t->peers);
     2745  ret = tr_new0 (tr_peer_stat, size);
     2746
     2747  for (i=0; i<size; ++i)
     2748    {
     2749      char *                   pch;
     2750      const tr_peer *          peer = peers[i];
     2751      const struct peer_atom * atom = peer->atom;
     2752      tr_peer_stat *           stat = ret + i;
     2753
     2754      tr_address_to_string_with_buf (&atom->addr, stat->addr, sizeof (stat->addr));
     2755      tr_strlcpy (stat->client, (peer->client ? peer->client : ""), sizeof (stat->client));
     2756      stat->port                = ntohs (peer->atom->port);
     2757      stat->from                = atom->fromFirst;
     2758      stat->progress            = peer->progress;
     2759      stat->isUTP               = peer->io->utp_socket != NULL;
     2760      stat->isEncrypted         = tr_peerIoIsEncrypted (peer->io) ? 1 : 0;
     2761      stat->rateToPeer_KBps     = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_CLIENT_TO_PEER));
     2762      stat->rateToClient_KBps   = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_PEER_TO_CLIENT));
     2763      stat->peerIsChoked        = peer->peerIsChoked;
     2764      stat->peerIsInterested    = peer->peerIsInterested;
     2765      stat->clientIsChoked      = peer->clientIsChoked;
     2766      stat->clientIsInterested  = peer->clientIsInterested;
     2767      stat->isIncoming          = tr_peerIoIsIncoming (peer->io);
     2768      stat->isDownloadingFrom   = clientIsDownloadingFrom (tor, peer);
     2769      stat->isUploadingTo       = clientIsUploadingTo (peer);
     2770      stat->isSeed              = peerIsSeed (peer);
     2771
     2772      stat->blocksToPeer        = tr_historyGet (&peer->blocksSentToPeer,    now, CANCEL_HISTORY_SEC);
     2773      stat->blocksToClient      = tr_historyGet (&peer->blocksSentToClient,  now, CANCEL_HISTORY_SEC);
     2774      stat->cancelsToPeer       = tr_historyGet (&peer->cancelsSentToPeer,   now, CANCEL_HISTORY_SEC);
     2775      stat->cancelsToClient     = tr_historyGet (&peer->cancelsSentToClient, now, CANCEL_HISTORY_SEC);
     2776
     2777      stat->pendingReqsToPeer   = peer->pendingReqsToPeer;
     2778      stat->pendingReqsToClient = peer->pendingReqsToClient;
     2779
     2780      pch = stat->flagStr;
     2781      if (stat->isUTP) *pch++ = 'T';
     2782      if (t->optimistic == peer) *pch++ = 'O';
     2783      if (stat->isDownloadingFrom) *pch++ = 'D';
     2784      else if (stat->clientIsInterested) *pch++ = 'd';
     2785      if (stat->isUploadingTo) *pch++ = 'U';
     2786      else if (stat->peerIsInterested) *pch++ = 'u';
     2787      if (!stat->clientIsChoked && !stat->clientIsInterested) *pch++ = 'K';
     2788      if (!stat->peerIsChoked && !stat->peerIsInterested) *pch++ = '?';
     2789      if (stat->isEncrypted) *pch++ = 'E';
     2790      if (stat->from == TR_PEER_FROM_DHT) *pch++ = 'H';
     2791      else if (stat->from == TR_PEER_FROM_PEX) *pch++ = 'X';
     2792      if (stat->isIncoming) *pch++ = 'I';
     2793      *pch = '\0';
    27982794    }
    27992795
  • trunk/libtransmission/peer-mgr.h

    r13651 r13670  
    226226void tr_peerMgrRemoveTorrent (tr_torrent * tor);
    227227
    228 void tr_peerMgrTorrentAvailability (tr_torrent   * tor,
    229                                     int8_t       * tab,
    230                                     unsigned int   tabCount);
     228void tr_peerMgrTorrentAvailability (const tr_torrent   * tor,
     229                                    int8_t             * tab,
     230                                    unsigned int         tabCount);
    231231
    232232uint64_t tr_peerMgrGetDesiredAvailable (const tr_torrent * tor);
     
    243243                             int * setmePeersFrom); /* TR_PEER_FROM__MAX */
    244244
    245 struct tr_peer_stat* tr_peerMgrPeerStats (tr_torrent * tor,
    246                                           int        * setmeCount);
    247 
    248 double* tr_peerMgrWebSpeeds_KBps (tr_torrent * tor);
     245struct tr_peer_stat* tr_peerMgrPeerStats (const tr_torrent * tor,
     246                                          int              * setmeCount);
     247
     248double* tr_peerMgrWebSpeeds_KBps (const tr_torrent * tor);
    249249
    250250
  • trunk/libtransmission/session.c

    r13667 r13670  
    17701770    qsort (torrents, n, sizeof (tr_torrent*), compareTorrentByCur);
    17711771    for (i = 0; i < n; ++i)
    1772         tr_torrentUnref (torrents[i]);
     1772        tr_torrentFree (torrents[i]);
    17731773    tr_free (torrents);
    17741774
  • trunk/libtransmission/torrent.c

    r13667 r13670  
    153153
    154154bool
    155 tr_torrentIsPieceTransferAllowed (tr_torrent   * tor,
    156                                   tr_direction   direction)
    157 {
    158   bool allowed = false;
    159 
     155tr_torrentIsPieceTransferAllowed (const tr_torrent  * tor,
     156                                  tr_direction        direction)
     157{
     158  bool allowed = true;
     159  unsigned int limit;
     160
     161  assert (tr_isTorrent (tor));
    160162  assert (tr_isDirection (direction));
    161163
    162   if (tr_torrentRef (tor))
    163     {
    164       unsigned int limit;
    165 
    166       allowed = true;
    167 
    168       if (tr_torrentUsesSpeedLimit (tor, direction))
    169         if (tr_torrentGetSpeedLimit_Bps (tor, direction) <= 0)
    170           allowed = false;
    171 
    172       if (tr_torrentUsesSessionLimits (tor))
    173         if (tr_sessionGetActiveSpeedLimit_Bps (tor->session, direction, &limit))
    174           if (limit <= 0)
    175             allowed = false;
    176 
    177       tr_torrentUnref (tor);
    178     }
     164  if (tr_torrentUsesSpeedLimit (tor, direction))
     165    if (tr_torrentGetSpeedLimit_Bps (tor, direction) <= 0)
     166      allowed = false;
     167
     168  if (tr_torrentUsesSessionLimits (tor))
     169    if (tr_sessionGetActiveSpeedLimit_Bps (tor->session, direction, &limit))
     170      if (limit <= 0)
     171        allowed = false;
    179172
    180173  return allowed;
     
    209202}
    210203unsigned int
    211 tr_torrentGetSpeedLimit_KBps (tr_torrent * tor, tr_direction dir)
    212 {
    213   unsigned int limit = 0;
    214 
    215   assert (tr_isDirection (dir));
    216 
    217   if (tr_torrentRef (tor))
    218     {
    219       limit = toSpeedKBps (tr_torrentGetSpeedLimit_Bps (tor, dir));
    220       tr_torrentUnref (tor);
    221     }
    222 
    223   return limit;
    224 }
    225 
    226 void
    227 tr_torrentUseSpeedLimit (tr_torrent * tor, tr_direction dir, bool do_use)
     204tr_torrentGetSpeedLimit_KBps (const tr_torrent * tor, tr_direction dir)
    228205{
    229206  assert (tr_isTorrent (tor));
    230207  assert (tr_isDirection (dir));
    231208
     209  return toSpeedKBps (tr_torrentGetSpeedLimit_Bps (tor, dir));
     210}
     211
     212void
     213tr_torrentUseSpeedLimit (tr_torrent * tor, tr_direction dir, bool do_use)
     214{
     215  assert (tr_isTorrent (tor));
     216  assert (tr_isDirection (dir));
     217
    232218  if (tr_bandwidthSetLimited (&tor->bandwidth, dir, do_use))
    233219    tr_torrentSetDirty (tor);
     
    235221
    236222bool
    237 tr_torrentUsesSpeedLimit (tr_torrent * tor, tr_direction dir)
    238 {
    239   bool limited = false;
    240 
    241   if (tr_torrentRef (tor))
    242     {
    243       limited = tr_bandwidthIsLimited (&tor->bandwidth, dir);
    244       tr_torrentUnref (tor);
    245     }
    246 
    247   return limited;
     223tr_torrentUsesSpeedLimit (const tr_torrent * tor, tr_direction dir)
     224{
     225  assert (tr_isTorrent (tor));
     226
     227  return tr_bandwidthIsLimited (&tor->bandwidth, dir);
    248228}
    249229
     
    263243
    264244bool
    265 tr_torrentUsesSessionLimits (tr_torrent * tor)
    266 {
    267   bool limited = false;
    268 
    269   if (tr_torrentRef (tor))
    270     {
    271       limited = tr_bandwidthAreParentLimitsHonored (&tor->bandwidth, TR_UP);
    272       tr_torrentUnref (tor);
    273     }
    274 
    275   return limited;
     245tr_torrentUsesSessionLimits (const tr_torrent * tor)
     246{
     247  assert (tr_isTorrent (tor));
     248
     249  return tr_bandwidthAreParentLimitsHonored (&tor->bandwidth, TR_UP);
    276250}
    277251
     
    316290
    317291double
    318 tr_torrentGetRatioLimit (tr_torrent * tor)
    319 {
    320   double limit = 0;
    321 
    322   if (tr_torrentRef (tor))
    323     {
    324       limit = tor->desiredRatio;
    325       tr_torrentUnref (tor);
    326     }
    327 
    328   return limit;
     292tr_torrentGetRatioLimit (const tr_torrent * tor)
     293{
     294  assert (tr_isTorrent (tor));
     295
     296  return tor->desiredRatio;
    329297}
    330298
    331299bool
    332 tr_torrentGetSeedRatio (tr_torrent * tor, double * ratio)
    333 {
    334   bool isLimited = false;
    335 
    336   if (tr_torrentRef (tor))
    337     {
    338       switch (tr_torrentGetRatioMode (tor))
    339         {
    340           case TR_RATIOLIMIT_SINGLE:
    341             isLimited = true;
    342             if (ratio)
    343               *ratio = tr_torrentGetRatioLimit (tor);
    344             break;
    345 
    346           case TR_RATIOLIMIT_GLOBAL:
    347             isLimited = tr_sessionIsRatioLimited (tor->session);
    348             if (isLimited && ratio)
    349               *ratio = tr_sessionGetRatioLimit (tor->session);
    350             break;
    351 
    352           default: /* TR_RATIOLIMIT_UNLIMITED */
    353             isLimited = false;
    354             break;
    355         }
    356 
    357       tr_torrentUnref (tor);
     300tr_torrentGetSeedRatio (const tr_torrent * tor, double * ratio)
     301{
     302  bool isLimited;
     303
     304  assert (tr_isTorrent (tor));
     305
     306  switch (tr_torrentGetRatioMode (tor))
     307    {
     308      case TR_RATIOLIMIT_SINGLE:
     309        isLimited = true;
     310        if (ratio)
     311          *ratio = tr_torrentGetRatioLimit (tor);
     312        break;
     313
     314      case TR_RATIOLIMIT_GLOBAL:
     315        isLimited = tr_sessionIsRatioLimited (tor->session);
     316        if (isLimited && ratio)
     317          *ratio = tr_sessionGetRatioLimit (tor->session);
     318        break;
     319
     320      default: /* TR_RATIOLIMIT_UNLIMITED */
     321        isLimited = false;
     322        break;
    358323    }
    359324
     
    364329 * it applies if the torrent's a seed AND it has a seed ratio set */
    365330static bool
    366 tr_torrentGetSeedRatioBytes (tr_torrent  * tor,
    367                              uint64_t    * setmeLeft,
    368                              uint64_t    * setmeGoal)
    369 {
    370     double seedRatio;
    371     bool seedRatioApplies = false;
    372 
    373     if (tr_torrentGetSeedRatio (tor, &seedRatio))
    374     {
    375         const uint64_t u = tor->uploadedCur + tor->uploadedPrev;
    376         const uint64_t d = tor->downloadedCur + tor->downloadedPrev;
    377         const uint64_t baseline = d ? d : tr_cpSizeWhenDone (&tor->completion);
    378         const uint64_t goal = baseline * seedRatio;
    379         if (setmeLeft) *setmeLeft = goal > u ? goal - u : 0;
    380         if (setmeGoal) *setmeGoal = goal;
    381         seedRatioApplies = tr_torrentIsSeed (tor);
    382     }
    383 
    384     return seedRatioApplies;
     331tr_torrentGetSeedRatioBytes (const tr_torrent  * tor,
     332                             uint64_t          * setmeLeft,
     333                             uint64_t          * setmeGoal)
     334{
     335  double seedRatio;
     336  bool seedRatioApplies = false;
     337
     338  assert (tr_isTorrent (tor));
     339
     340  if (tr_torrentGetSeedRatio (tor, &seedRatio))
     341    {
     342      const uint64_t u = tor->uploadedCur + tor->uploadedPrev;
     343      const uint64_t d = tor->downloadedCur + tor->downloadedPrev;
     344      const uint64_t baseline = d ? d : tr_cpSizeWhenDone (&tor->completion);
     345      const uint64_t goal = baseline * seedRatio;
     346      if (setmeLeft) *setmeLeft = goal > u ? goal - u : 0;
     347      if (setmeGoal) *setmeGoal = goal;
     348      seedRatioApplies = tr_torrentIsSeed (tor);
     349    }
     350
     351  return seedRatioApplies;
    385352}
    386353
    387354static bool
    388 tr_torrentIsSeedRatioDone (tr_torrent * tor)
     355tr_torrentIsSeedRatioDone (const tr_torrent * tor)
    389356{
    390357    uint64_t bytesLeft;
     
    851818    tor->uniqueId = nextUniqueId++;
    852819    tor->magicNumber = TORRENT_MAGIC_NUMBER;
    853     tor->refCount = 1;
    854820    tor->queuePosition = session->torrentCount;
    855821
     
    11931159
    11941160static double
    1195 getVerifyProgress (tr_torrent * tor)
     1161getVerifyProgress (const tr_torrent * tor)
    11961162{
    11971163  double d = 0;
    11981164
    1199   if (tr_torrentRef (tor))
    1200     {
    1201       if (tr_torrentHasMetadata (tor))
    1202         {
    1203           tr_piece_index_t i, n;
    1204           tr_piece_index_t checked = 0;
    1205 
    1206           for (i=0, n=tor->info.pieceCount; i!=n; ++i)
    1207             if (tor->info.pieces[i].timeChecked)
    1208               ++checked;
    1209 
    1210           d = checked / (double)tor->info.pieceCount;
    1211         }
    1212 
    1213       tr_torrentUnref (tor);
     1165  if (tr_torrentHasMetadata (tor))
     1166    {
     1167      tr_piece_index_t i, n;
     1168      tr_piece_index_t checked = 0;
     1169
     1170      for (i=0, n=tor->info.pieceCount; i!=n; ++i)
     1171        if (tor->info.pieces[i].timeChecked)
     1172          ++checked;
     1173
     1174      d = checked / (double)tor->info.pieceCount;
    12141175    }
    12151176
     
    12201181tr_torrentStat (tr_torrent * tor)
    12211182{
    1222     tr_stat *               s;
    1223     uint64_t                now;
    1224     uint64_t                seedRatioBytesLeft;
    1225     uint64_t                seedRatioBytesGoal;
    1226     bool                    seedRatioApplies;
    1227     uint16_t                seedIdleMinutes;
    1228 
    1229     if (!tr_torrentRef(tor))
    1230         return NULL;
    1231 
    1232     tor->lastStatTime = tr_time ();
    1233 
    1234     s = &tor->stats;
    1235     s->id = tor->uniqueId;
    1236     s->activity = tr_torrentGetActivity (tor);
    1237     s->error = tor->error;
    1238     s->queuePosition = tor->queuePosition;
    1239     s->isStalled = tr_torrentIsStalled (tor);
    1240     tr_strlcpy (s->errorString, tor->errorString, sizeof (s->errorString));
    1241 
    1242     s->manualAnnounceTime = tr_announcerNextManualAnnounce (tor);
    1243 
    1244     tr_peerMgrTorrentStats (tor,
    1245                             &s->peersConnected,
    1246                             &s->webseedsSendingToUs,
    1247                             &s->peersSendingToUs,
    1248                             &s->peersGettingFromUs,
    1249                             s->peersFrom);
    1250 
    1251     now = tr_time_msec ();
    1252     s->rawUploadSpeed_KBps     = toSpeedKBps (tr_bandwidthGetRawSpeed_Bps (&tor->bandwidth, now, TR_UP));
    1253     s->pieceUploadSpeed_KBps   = toSpeedKBps (tr_bandwidthGetPieceSpeed_Bps (&tor->bandwidth, now, TR_UP));
    1254     s->rawDownloadSpeed_KBps   = toSpeedKBps (tr_bandwidthGetRawSpeed_Bps (&tor->bandwidth, now, TR_DOWN));
    1255     s->pieceDownloadSpeed_KBps = toSpeedKBps (tr_bandwidthGetPieceSpeed_Bps (&tor->bandwidth, now, TR_DOWN));
    1256 
    1257     s->percentComplete = tr_cpPercentComplete (&tor->completion);
    1258     s->metadataPercentComplete = tr_torrentGetMetadataPercent (tor);
    1259 
    1260     s->percentDone         = tr_cpPercentDone (&tor->completion);
    1261     s->leftUntilDone       = tr_cpLeftUntilDone (&tor->completion);
    1262     s->sizeWhenDone        = tr_cpSizeWhenDone (&tor->completion);
    1263     s->recheckProgress     = s->activity == TR_STATUS_CHECK ? getVerifyProgress (tor) : 0;
    1264     s->activityDate        = tor->activityDate;
    1265     s->addedDate           = tor->addedDate;
    1266     s->doneDate            = tor->doneDate;
    1267     s->startDate           = tor->startDate;
    1268     s->secondsSeeding      = tor->secondsSeeding;
    1269     s->secondsDownloading  = tor->secondsDownloading;
    1270     s->idleSecs            = torrentGetIdleSecs (tor);
    1271 
    1272     s->corruptEver      = tor->corruptCur    + tor->corruptPrev;
    1273     s->downloadedEver   = tor->downloadedCur + tor->downloadedPrev;
    1274     s->uploadedEver     = tor->uploadedCur   + tor->uploadedPrev;
    1275     s->haveValid        = tr_cpHaveValid (&tor->completion);
    1276     s->haveUnchecked    = tr_cpHaveTotal (&tor->completion) - s->haveValid;
    1277     s->desiredAvailable = tr_peerMgrGetDesiredAvailable (tor);
    1278 
    1279     s->ratio = tr_getRatio (s->uploadedEver,
    1280                             s->downloadedEver ? s->downloadedEver : s->haveValid);
    1281 
    1282     seedRatioApplies = tr_torrentGetSeedRatioBytes (tor, &seedRatioBytesLeft,
    1283                                                          &seedRatioBytesGoal);
    1284 
    1285     switch (s->activity)
    1286     {
    1287         /* etaXLSpeed exists because if we use the piece speed directly,
    1288          * brief fluctuations cause the ETA to jump all over the place.
    1289          * so, etaXLSpeed is a smoothed-out version of the piece speed
    1290          * to dampen the effect of fluctuations */
    1291 
    1292         case TR_STATUS_DOWNLOAD:
    1293             if ((tor->etaDLSpeedCalculatedAt + 800) < now) {
    1294                 tor->etaDLSpeed_KBps = ((tor->etaDLSpeedCalculatedAt + 4000) < now)
    1295                     ? s->pieceDownloadSpeed_KBps /* if no recent previous speed, no need to smooth */
    1296                     : ((tor->etaDLSpeed_KBps*4.0) + s->pieceDownloadSpeed_KBps)/5.0; /* smooth across 5 readings */
    1297                 tor->etaDLSpeedCalculatedAt = now;
    1298             }
    1299 
    1300             if (s->leftUntilDone > s->desiredAvailable)
    1301                 s->eta = TR_ETA_NOT_AVAIL;
    1302             else if (tor->etaDLSpeed_KBps < 1)
    1303                 s->eta = TR_ETA_UNKNOWN;
     1183  tr_stat * s;
     1184  uint64_t seedRatioBytesLeft;
     1185  uint64_t seedRatioBytesGoal;
     1186  bool seedRatioApplies;
     1187  uint16_t seedIdleMinutes;
     1188  const uint64_t now = tr_time_msec ();
     1189
     1190  assert (tr_isTorrent (tor));
     1191
     1192  tor->lastStatTime = tr_time ();
     1193
     1194  s = &tor->stats;
     1195  s->id = tor->uniqueId;
     1196  s->activity = tr_torrentGetActivity (tor);
     1197  s->error = tor->error;
     1198  s->queuePosition = tor->queuePosition;
     1199  s->isStalled = tr_torrentIsStalled (tor);
     1200  tr_strlcpy (s->errorString, tor->errorString, sizeof (s->errorString));
     1201
     1202  s->manualAnnounceTime = tr_announcerNextManualAnnounce (tor);
     1203
     1204  tr_peerMgrTorrentStats (tor,
     1205                          &s->peersConnected,
     1206                          &s->webseedsSendingToUs,
     1207                          &s->peersSendingToUs,
     1208                          &s->peersGettingFromUs,
     1209                          s->peersFrom);
     1210
     1211  s->rawUploadSpeed_KBps     = toSpeedKBps (tr_bandwidthGetRawSpeed_Bps (&tor->bandwidth, now, TR_UP));
     1212  s->pieceUploadSpeed_KBps   = toSpeedKBps (tr_bandwidthGetPieceSpeed_Bps (&tor->bandwidth, now, TR_UP));
     1213  s->rawDownloadSpeed_KBps   = toSpeedKBps (tr_bandwidthGetRawSpeed_Bps (&tor->bandwidth, now, TR_DOWN));
     1214  s->pieceDownloadSpeed_KBps = toSpeedKBps (tr_bandwidthGetPieceSpeed_Bps (&tor->bandwidth, now, TR_DOWN));
     1215
     1216  s->percentComplete = tr_cpPercentComplete (&tor->completion);
     1217  s->metadataPercentComplete = tr_torrentGetMetadataPercent (tor);
     1218
     1219  s->percentDone         = tr_cpPercentDone (&tor->completion);
     1220  s->leftUntilDone       = tr_cpLeftUntilDone (&tor->completion);
     1221  s->sizeWhenDone        = tr_cpSizeWhenDone (&tor->completion);
     1222  s->recheckProgress     = s->activity == TR_STATUS_CHECK ? getVerifyProgress (tor) : 0;
     1223  s->activityDate        = tor->activityDate;
     1224  s->addedDate           = tor->addedDate;
     1225  s->doneDate            = tor->doneDate;
     1226  s->startDate           = tor->startDate;
     1227  s->secondsSeeding      = tor->secondsSeeding;
     1228  s->secondsDownloading  = tor->secondsDownloading;
     1229  s->idleSecs            = torrentGetIdleSecs (tor);
     1230
     1231  s->corruptEver      = tor->corruptCur    + tor->corruptPrev;
     1232  s->downloadedEver   = tor->downloadedCur + tor->downloadedPrev;
     1233  s->uploadedEver     = tor->uploadedCur   + tor->uploadedPrev;
     1234  s->haveValid        = tr_cpHaveValid (&tor->completion);
     1235  s->haveUnchecked    = tr_cpHaveTotal (&tor->completion) - s->haveValid;
     1236  s->desiredAvailable = tr_peerMgrGetDesiredAvailable (tor);
     1237
     1238  s->ratio = tr_getRatio (s->uploadedEver,
     1239                          s->downloadedEver ? s->downloadedEver : s->haveValid);
     1240
     1241  seedRatioApplies = tr_torrentGetSeedRatioBytes (tor, &seedRatioBytesLeft,
     1242                                                       &seedRatioBytesGoal);
     1243
     1244  switch (s->activity)
     1245    {
     1246      /* etaXLSpeed exists because if we use the piece speed directly,
     1247       * brief fluctuations cause the ETA to jump all over the place.
     1248       * so, etaXLSpeed is a smoothed-out version of the piece speed
     1249       * to dampen the effect of fluctuations */
     1250      case TR_STATUS_DOWNLOAD:
     1251        if ((tor->etaDLSpeedCalculatedAt + 800) < now)
     1252          {
     1253            tor->etaDLSpeed_KBps = ((tor->etaDLSpeedCalculatedAt + 4000) < now)
     1254              ? s->pieceDownloadSpeed_KBps /* if no recent previous speed, no need to smooth */
     1255              : ((tor->etaDLSpeed_KBps*4.0) + s->pieceDownloadSpeed_KBps)/5.0; /* smooth across 5 readings */
     1256            tor->etaDLSpeedCalculatedAt = now;
     1257          }
     1258
     1259        if (s->leftUntilDone > s->desiredAvailable)
     1260          s->eta = TR_ETA_NOT_AVAIL;
     1261        else if (tor->etaDLSpeed_KBps < 1)
     1262          s->eta = TR_ETA_UNKNOWN;
     1263        else
     1264          s->eta = s->leftUntilDone / toSpeedBytes (tor->etaDLSpeed_KBps);
     1265
     1266        s->etaIdle = TR_ETA_NOT_AVAIL;
     1267        break;
     1268
     1269      case TR_STATUS_SEED:
     1270        if (!seedRatioApplies)
     1271          {
     1272            s->eta = TR_ETA_NOT_AVAIL;
     1273          }
     1274        else
     1275          {
     1276            if ((tor->etaULSpeedCalculatedAt + 800) < now)
     1277              {
     1278                tor->etaULSpeed_KBps = ((tor->etaULSpeedCalculatedAt + 4000) < now)
     1279                  ? s->pieceUploadSpeed_KBps /* if no recent previous speed, no need to smooth */
     1280                  : ((tor->etaULSpeed_KBps*4.0) + s->pieceUploadSpeed_KBps)/5.0; /* smooth across 5 readings */
     1281                tor->etaULSpeedCalculatedAt = now;
     1282              }
     1283
     1284            if (tor->etaULSpeed_KBps < 1)
     1285              s->eta = TR_ETA_UNKNOWN;
    13041286            else
    1305                 s->eta = s->leftUntilDone / toSpeedBytes (tor->etaDLSpeed_KBps);
    1306 
    1307             s->etaIdle = TR_ETA_NOT_AVAIL;
    1308             break;
    1309 
    1310         case TR_STATUS_SEED: {
    1311             if (!seedRatioApplies)
    1312                 s->eta = TR_ETA_NOT_AVAIL;
    1313             else {
    1314                 if ((tor->etaULSpeedCalculatedAt + 800) < now) {
    1315                     tor->etaULSpeed_KBps = ((tor->etaULSpeedCalculatedAt + 4000) < now)
    1316                         ? s->pieceUploadSpeed_KBps /* if no recent previous speed, no need to smooth */
    1317                         : ((tor->etaULSpeed_KBps*4.0) + s->pieceUploadSpeed_KBps)/5.0; /* smooth across 5 readings */
    1318                     tor->etaULSpeedCalculatedAt = now;
    1319                 }
    1320                 if (tor->etaULSpeed_KBps < 1)
    1321                     s->eta = TR_ETA_UNKNOWN;
    1322                 else
    1323                     s->eta = seedRatioBytesLeft / toSpeedBytes (tor->etaULSpeed_KBps);
    1324             }
    1325 
    1326             if (tor->etaULSpeed_KBps < 1 && tr_torrentGetSeedIdle (tor, &seedIdleMinutes))
    1327                 s->etaIdle = seedIdleMinutes * 60 - s->idleSecs;
    1328             else
    1329                 s->etaIdle = TR_ETA_NOT_AVAIL;
    1330             break;
    1331         }
    1332 
    1333         default:
    1334             s->eta = TR_ETA_NOT_AVAIL;
    1335             s->etaIdle = TR_ETA_NOT_AVAIL;
    1336             break;
    1337     }
    1338 
    1339     /* s->haveValid is here to make sure a torrent isn't marked 'finished'
    1340      * when the user hits "uncheck all" prior to starting the torrent... */
    1341     s->finished = tor->finishedSeedingByIdle || (seedRatioApplies && !seedRatioBytesLeft && s->haveValid);
    1342 
    1343     if (!seedRatioApplies || s->finished)
    1344         s->seedRatioPercentDone = 1;
    1345     else if (!seedRatioBytesGoal) /* impossible? safeguard for div by zero */
    1346         s->seedRatioPercentDone = 0;
    1347     else
    1348         s->seedRatioPercentDone = (double)(seedRatioBytesGoal - seedRatioBytesLeft) / seedRatioBytesGoal;
    1349 
    1350     /* test some of the constraints */
    1351     assert (s->sizeWhenDone <= tor->info.totalSize);
    1352     assert (s->leftUntilDone <= s->sizeWhenDone);
    1353     assert (s->desiredAvailable <= s->leftUntilDone);
    1354 
    1355     tr_torrentUnref (tor);
    1356 
    1357     return s;
     1287              s->eta = seedRatioBytesLeft / toSpeedBytes (tor->etaULSpeed_KBps);
     1288          }
     1289
     1290        if (tor->etaULSpeed_KBps < 1 && tr_torrentGetSeedIdle (tor, &seedIdleMinutes))
     1291          s->etaIdle = seedIdleMinutes * 60 - s->idleSecs;
     1292        else
     1293          s->etaIdle = TR_ETA_NOT_AVAIL;
     1294        break;
     1295
     1296      default:
     1297        s->eta = TR_ETA_NOT_AVAIL;
     1298        s->etaIdle = TR_ETA_NOT_AVAIL;
     1299        break;
     1300    }
     1301
     1302  /* s->haveValid is here to make sure a torrent isn't marked 'finished'
     1303   * when the user hits "uncheck all" prior to starting the torrent... */
     1304  s->finished = tor->finishedSeedingByIdle || (seedRatioApplies && !seedRatioBytesLeft && s->haveValid);
     1305
     1306  if (!seedRatioApplies || s->finished)
     1307    s->seedRatioPercentDone = 1;
     1308  else if (!seedRatioBytesGoal) /* impossible? safeguard for div by zero */
     1309    s->seedRatioPercentDone = 0;
     1310  else
     1311    s->seedRatioPercentDone = (double)(seedRatioBytesGoal - seedRatioBytesLeft) / seedRatioBytesGoal;
     1312
     1313  /* test some of the constraints */
     1314  assert (s->sizeWhenDone <= tor->info.totalSize);
     1315  assert (s->leftUntilDone <= s->sizeWhenDone);
     1316  assert (s->desiredAvailable <= s->leftUntilDone);
     1317
     1318  return s;
    13581319}
    13591320
     
    14371398
    14381399double*
    1439 tr_torrentWebSpeeds_KBps (tr_torrent * tor)
    1440 {
    1441   double * ret = NULL;
    1442 
    1443   if (tr_torrentRef (tor))
    1444     {
    1445       ret = tr_peerMgrWebSpeeds_KBps (tor);
    1446       tr_torrentUnref (tor);
    1447     }
    1448 
    1449   return ret;
     1400tr_torrentWebSpeeds_KBps (const tr_torrent * tor)
     1401{
     1402  assert (tr_isTorrent (tor));
     1403
     1404  return tr_peerMgrWebSpeeds_KBps (tor);
    14501405}
    14511406
    14521407tr_peer_stat *
    1453 tr_torrentPeers (tr_torrent * tor, int * peerCount)
    1454 {
    1455   tr_peer_stat * ret = NULL;
    1456 
    1457   if (tr_torrentRef (tor))
    1458     {
    1459       ret = tr_peerMgrPeerStats (tor, peerCount);
    1460       tr_torrentUnref (tor);
    1461     }
    1462 
    1463   return ret;
     1408tr_torrentPeers (const tr_torrent * tor, int * peerCount)
     1409{
     1410  assert (tr_isTorrent (tor));
     1411
     1412  return tr_peerMgrPeerStats (tor, peerCount);
    14641413}
    14651414
     
    14711420
    14721421tr_tracker_stat *
    1473 tr_torrentTrackers (tr_torrent * torrent, int * setmeTrackerCount)
    1474 {
    1475   tr_tracker_stat * ret = NULL;
    1476 
    1477   if (tr_torrentRef (torrent))
    1478     {
    1479       ret = tr_announcerStats (torrent, setmeTrackerCount);
    1480       tr_torrentUnref (torrent);
    1481     }
    1482 
    1483   return ret;
     1422tr_torrentTrackers (const tr_torrent * tor, int * setmeTrackerCount)
     1423{
     1424  assert (tr_isTorrent (tor));
     1425
     1426  return tr_announcerStats (tor, setmeTrackerCount);
    14841427}
    14851428
     
    14871430tr_torrentTrackersFree (tr_tracker_stat * trackers, int trackerCount)
    14881431{
    1489     tr_announcerStatsFree (trackers, trackerCount);
    1490 }
    1491 
    1492 void
    1493 tr_torrentAvailability (tr_torrent * tor, int8_t * tab, int size)
    1494 {
    1495   if ((tab != NULL) && (size > 0) && tr_torrentRef (tor))
    1496     {
    1497       tr_peerMgrTorrentAvailability (tor, tab, size);
    1498       tr_torrentUnref (tor);
    1499     }
    1500 }
    1501 
    1502 void
    1503 tr_torrentAmountFinished (tr_torrent * tor, float * tab, int size)
    1504 {
    1505   if (tr_torrentRef (tor))
    1506     {
    1507       tr_cpGetAmountDone (&tor->completion, tab, size);
    1508       tr_torrentUnref (tor);
    1509     }
     1432  tr_announcerStatsFree (trackers, trackerCount);
     1433}
     1434
     1435void
     1436tr_torrentAvailability (const tr_torrent * tor, int8_t * tab, int size)
     1437{
     1438  assert (tr_isTorrent (tor));
     1439
     1440  if ((tab != NULL) && (size > 0))
     1441    tr_peerMgrTorrentAvailability (tor, tab, size);
     1442}
     1443
     1444void
     1445tr_torrentAmountFinished (const tr_torrent * tor, float * tab, int size)
     1446{
     1447  tr_cpGetAmountDone (&tor->completion, tab, size);
    15101448}
    15111449
     
    18131751  tr_torinf (tor, "%s", "Pausing");
    18141752
    1815   if (tr_torrentLock (tor))
    1816     {
    1817       tr_verifyRemove (tor);
    1818       torrentSetQueued (tor, false);
    1819       tr_peerMgrStopTorrent (tor);
    1820       tr_announcerTorrentStopped (tor);
    1821       tr_cacheFlushTorrent (tor->session->cache, tor);
    1822 
    1823       tr_fdTorrentClose (tor->session, tor->uniqueId);
    1824 
    1825       if (!tor->isDeleting)
    1826         tr_torrentSave (tor);
    1827 
    1828       tr_torrentUnlock (tor);
    1829     }
     1753  assert (tr_isTorrent (tor));
     1754
     1755  tr_torrentLock (tor);
     1756
     1757  tr_verifyRemove (tor);
     1758  torrentSetQueued (tor, false);
     1759  tr_peerMgrStopTorrent (tor);
     1760  tr_announcerTorrentStopped (tor);
     1761  tr_cacheFlushTorrent (tor->session->cache, tor);
     1762
     1763  tr_fdTorrentClose (tor->session, tor->uniqueId);
     1764
     1765  if (!tor->isDeleting)
     1766    tr_torrentSave (tor);
     1767
     1768  tr_torrentUnlock (tor);
    18301769}
    18311770
     
    18751814
    18761815void
    1877 tr_torrentUnref (tr_torrent * tor)
    1878 {
    1879   assert (tr_isTorrent (tor));
    1880 
    1881   if (tor->refCount > 1)
    1882     {
    1883       --tor->refCount;
    1884     }
    1885   else if (tor->refCount == 1)
    1886     {
    1887       tr_session * session = tor->session;
    1888 
    1889       tr_sessionLock (session);
    1890       tr_torrentClearCompletenessCallback (tor);
    1891       tr_runInEventThread (session, closeTorrent, tor);
    1892       tr_sessionUnlock (session);
    1893 
    1894       --tor->refCount;
    1895     }
    1896 }
    1897 
    1898 bool
    1899 tr_torrentLock (const tr_torrent * tor)
    1900 {
    1901   if (!tr_isTorrent (tor))
    1902     return false;
    1903 
    1904   tr_sessionLock (tor->session);
    1905   return true;
    1906 }
    1907 
    1908 bool
    1909 tr_torrentRef (tr_torrent * tor)
    1910 {
    1911   if (!tr_isTorrent (tor))
    1912     return false;
    1913 
    1914   ++tor->refCount;
    1915   return true;
     1816tr_torrentFree (tr_torrent * tor)
     1817{
     1818  if (tr_isTorrent (tor))
     1819    {
     1820      tr_session * session = tor->session;
     1821      assert (tr_isSession (session));
     1822      tr_sessionLock (session);
     1823
     1824      tr_torrentClearCompletenessCallback (tor);
     1825      tr_runInEventThread (session, closeTorrent, tor);
     1826
     1827      tr_sessionUnlock (session);
     1828    }
    19161829}
    19171830
     
    20972010tr_torrentRecheckCompleteness (tr_torrent * tor)
    20982011{
    2099   if (tr_torrentLock (tor))
    2100     {
    2101       const tr_completeness completeness = tr_cpGetStatus (&tor->completion);
    2102 
    2103       if (completeness != tor->completeness)
     2012  tr_completeness completeness;
     2013
     2014  tr_torrentLock (tor);
     2015
     2016  completeness = tr_cpGetStatus (&tor->completion);
     2017  if (completeness != tor->completeness)
     2018    {
     2019      const int recentChange = tor->downloadedCur != 0;
     2020      const bool wasLeeching = !tr_torrentIsSeed (tor);
     2021      const bool wasRunning = tor->isRunning;
     2022
     2023      if (recentChange)
     2024        tr_torinf (tor, _("State changed from \"%1$s\" to \"%2$s\""),
     2025                   getCompletionString (tor->completeness),
     2026                   getCompletionString (completeness));
     2027
     2028      tor->completeness = completeness;
     2029      tr_fdTorrentClose (tor->session, tor->uniqueId);
     2030
     2031      fireCompletenessChange (tor, completeness, wasRunning);
     2032
     2033      if (tr_torrentIsSeed (tor))
    21042034        {
    2105           const int recentChange = tor->downloadedCur != 0;
    2106           const bool wasLeeching = !tr_torrentIsSeed (tor);
    2107           const bool wasRunning = tor->isRunning;
    2108 
    21092035          if (recentChange)
    2110             tr_torinf (tor, _("State changed from \"%1$s\" to \"%2$s\""),
    2111                        getCompletionString (tor->completeness),
    2112                        getCompletionString (completeness));
    2113 
    2114           tor->completeness = completeness;
    2115           tr_fdTorrentClose (tor->session, tor->uniqueId);
    2116 
    2117           fireCompletenessChange (tor, completeness, wasRunning);
    2118 
    2119           if (tr_torrentIsSeed (tor))
    21202036            {
    2121               if (recentChange)
    2122                 {
    2123                   tr_announcerTorrentCompleted (tor);
    2124                   tor->doneDate = tor->anyDate = tr_time ();
    2125                 }
    2126 
    2127               if (wasLeeching && wasRunning)
    2128                 {
    2129                   /* clear interested flag on all peers */
    2130                   tr_peerMgrClearInterest (tor);
    2131 
    2132                   /* if completeness was TR_LEECH then the seed limit check will have been skipped in bandwidthPulse */
    2133                   tr_torrentCheckSeedLimit (tor);
    2134                 }
    2135 
    2136               if (tor->currentDir == tor->incompleteDir)
    2137                 tr_torrentSetLocation (tor, tor->downloadDir, true, NULL, NULL);
    2138 
    2139               if (tr_sessionIsTorrentDoneScriptEnabled (tor->session))
    2140                 torrentCallScript (tor, tr_sessionGetTorrentDoneScript (tor->session));
     2037              tr_announcerTorrentCompleted (tor);
     2038              tor->doneDate = tor->anyDate = tr_time ();
    21412039            }
    21422040
    2143           tr_torrentSetDirty (tor);
     2041          if (wasLeeching && wasRunning)
     2042            {
     2043              /* clear interested flag on all peers */
     2044              tr_peerMgrClearInterest (tor);
     2045
     2046              /* if completeness was TR_LEECH then the seed limit check will have been skipped in bandwidthPulse */
     2047              tr_torrentCheckSeedLimit (tor);
     2048            }
     2049
     2050          if (tor->currentDir == tor->incompleteDir)
     2051            tr_torrentSetLocation (tor, tor->downloadDir, true, NULL, NULL);
     2052
     2053          if (tr_sessionIsTorrentDoneScriptEnabled (tor->session))
     2054            torrentCallScript (tor, tr_sessionGetTorrentDoneScript (tor->session));
    21442055        }
    21452056
    2146       tr_torrentUnlock (tor);
    2147     }
     2057      tr_torrentSetDirty (tor);
     2058    }
     2059
     2060  tr_torrentUnlock (tor);
    21482061}
    21492062
     
    22152128
    22162129tr_priority_t*
    2217 tr_torrentGetFilePriorities (tr_torrent * tor)
     2130tr_torrentGetFilePriorities (const tr_torrent * tor)
    22182131{
    22192132  tr_file_index_t i;
    2220   tr_priority_t * p = NULL;
    2221 
    2222   if (tr_torrentRef (tor))
    2223     {
    2224       p = tr_new0 (tr_priority_t, tor->info.fileCount);
    2225 
    2226       for (i=0; i<tor->info.fileCount; ++i)
    2227         p[i] = tor->info.files[i].priority;
    2228 
    2229       tr_torrentUnref (tor);
    2230     }
     2133  tr_priority_t * p;
     2134
     2135  assert (tr_isTorrent (tor));
     2136
     2137  p = tr_new0 (tr_priority_t, tor->info.fileCount);
     2138
     2139  for (i=0; i<tor->info.fileCount; ++i)
     2140    p[i] = tor->info.files[i].priority;
    22312141
    22322142  return p;
  • trunk/libtransmission/torrent.h

    r13651 r13670  
    3030**/
    3131
     32void        tr_torrentFree (tr_torrent * tor);
     33
    3234void        tr_ctorSetSave (tr_ctor * ctor,
    3335                            bool      saveMetadataInOurTorrentsDir);
     
    6365                                              const uint8_t * hash);
    6466
    65 bool        tr_torrentIsPieceTransferAllowed (tr_torrent    * torrent,
    66                                               tr_direction    direction);
     67bool        tr_torrentIsPieceTransferAllowed (const tr_torrent  * torrent,
     68                                              tr_direction        direction);
    6769
    6870
     
    139141
    140142    int                      magicNumber;
    141 
    142     size_t                   refCount;
    143143
    144144    tr_stat_errtype          error;
     
    303303}
    304304
    305 bool tr_torrentLock (const tr_torrent * tor);
    306 
     305static inline void tr_torrentLock (const tr_torrent * tor)
     306{
     307  tr_sessionLock (tor->session);
     308}
    307309static inline bool tr_torrentIsLocked (const tr_torrent * tor)
    308310{
    309     return tr_sessionIsLocked (tor->session);
    310 }
    311 
     311  return tr_sessionIsLocked (tor->session);
     312}
    312313static inline void tr_torrentUnlock (const tr_torrent * tor)
    313314{
    314     tr_sessionUnlock (tor->session);
     315  tr_sessionUnlock (tor->session);
    315316}
    316317
     
    366367    return (tor != NULL)
    367368        && (tor->magicNumber == TORRENT_MAGIC_NUMBER)
    368         && (tor->refCount > 0)
    369369        && (tr_isSession (tor->session));
    370370}
  • trunk/libtransmission/transmission.h

    r13667 r13670  
    11461146    @{ */
    11471147
    1148 /**
    1149  * @brief Decrements a torrent's refcount.
    1150  *
    1151  * If its refcount becomes zero, the torrent is stopped and its memory is freed.
    1152  */
    1153 void tr_torrentUnref (tr_torrent * torrent);
    1154 
    1155 /**
    1156  * @brief Increments a torrent's refcount.
    1157  *
    1158  * @return true if the pointer is a live torrent object.
    1159  *         This is a convenience for validity checking before use:
    1160  *         if (tr_torrentRef (tor)) { foo(); bar(); tr_torrentUnref(tor); }
    1161  */
    1162 bool tr_torrentRef (tr_torrent * torrent);
    1163 
    11641148typedef int tr_fileFunc (const char * filename);
    11651149
    1166 /** @brief Removes our .torrent and .resume files for
    1167            this torrent, then calls tr_torrentFree (). */
     1150/** @brief Removes our .torrent and .resume files for this torrent */
    11681151void tr_torrentRemove (tr_torrent  * torrent,
    11691152                       bool          removeLocalData,
     
    12391222
    12401223void         tr_torrentSetSpeedLimit_KBps (tr_torrent *, tr_direction, unsigned int KBps);
    1241 unsigned int tr_torrentGetSpeedLimit_KBps (tr_torrent *, tr_direction);
     1224unsigned int tr_torrentGetSpeedLimit_KBps (const tr_torrent *, tr_direction);
    12421225
    12431226void         tr_torrentUseSpeedLimit      (tr_torrent *, tr_direction, bool);
    1244 bool         tr_torrentUsesSpeedLimit     (tr_torrent *, tr_direction);
     1227bool         tr_torrentUsesSpeedLimit     (const tr_torrent *, tr_direction);
    12451228
    12461229void         tr_torrentUseSessionLimits   (tr_torrent *, bool);
    1247 bool         tr_torrentUsesSessionLimits  (tr_torrent *);
     1230bool         tr_torrentUsesSessionLimits  (const tr_torrent *);
    12481231
    12491232
     
    12731256                                       double              ratio);
    12741257
    1275 double        tr_torrentGetRatioLimit (tr_torrent  * tor);
    1276 
    1277 
    1278 bool          tr_torrentGetSeedRatio  (tr_torrent *, double * ratio);
     1258double        tr_torrentGetRatioLimit (const tr_torrent  * tor);
     1259
     1260
     1261bool          tr_torrentGetSeedRatio  (const tr_torrent *, double * ratio);
    12791262
    12801263
     
    13451328 *         It's the caller's responsibility to free () this.
    13461329 */
    1347 tr_priority_t*  tr_torrentGetFilePriorities (tr_torrent * torrent);
     1330tr_priority_t*  tr_torrentGetFilePriorities (const tr_torrent * torrent);
    13481331
    13491332/** @brief Set a batch of files to be downloaded or not. */
     
    15801563tr_peer_stat;
    15811564
    1582 tr_peer_stat * tr_torrentPeers (tr_torrent * torrent,
    1583                                 int        * peerCount);
     1565tr_peer_stat * tr_torrentPeers (const tr_torrent * torrent,
     1566                                int              * peerCount);
    15841567
    15851568void           tr_torrentPeersFree (tr_peer_stat * peerStats,
     
    17031686tr_tracker_stat;
    17041687
    1705 tr_tracker_stat * tr_torrentTrackers (tr_torrent * torrent,
    1706                                       int        * setmeTrackerCount);
     1688tr_tracker_stat * tr_torrentTrackers (const tr_torrent * torrent,
     1689                                      int              * setmeTrackerCount);
    17071690
    17081691void tr_torrentTrackersFree (tr_tracker_stat * trackerStats,
     
    17211704 *         NOTE: always free this array with tr_free () when you're done with it.
    17221705 */
    1723 double*  tr_torrentWebSpeeds_KBps (tr_torrent * torrent);
     1706double*  tr_torrentWebSpeeds_KBps (const tr_torrent * torrent);
    17241707
    17251708typedef struct tr_file_stat
     
    17451728 * of connected peers who have the piece.
    17461729 **********************************************************************/
    1747 void tr_torrentAvailability (tr_torrent  * torrent,
    1748                              int8_t      * tab,
    1749                              int           size);
    1750 
    1751 void tr_torrentAmountFinished (tr_torrent  * torrent,
    1752                                float       * tab,
    1753                                int           size);
     1730void tr_torrentAvailability (const tr_torrent  * torrent,
     1731                             int8_t            * tab,
     1732                             int                 size);
     1733
     1734void tr_torrentAmountFinished (const tr_torrent  * torrent,
     1735                               float             * tab,
     1736                               int                 size);
    17541737
    17551738void tr_torrentVerify (tr_torrent * torrent);
Note: See TracChangeset for help on using the changeset viewer.