Ignore:
Timestamp:
Dec 12, 2012, 8:22:57 PM (9 years ago)
Author:
jordan
Message:

(trunk) #5168 'make libtransmission's public funcs nonblocking when possible' -- first attempt.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/peer-mgr.c

    r13631 r13651  
    25502550
    25512551void
    2552 tr_peerMgrTorrentAvailability (const tr_torrent * tor, int8_t * tab, unsigned int tabCount)
    2553 {
    2554     assert (tr_isTorrent (tor));
    2555     assert (torrentIsLocked (tor->torrentPeers));
    2556     assert (tab != NULL);
    2557     assert (tabCount > 0);
    2558 
    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)
     2552tr_peerMgrTorrentAvailability (tr_torrent * tor, int8_t * tab, unsigned int tabCount)
     2553{
     2554  assert (tab != NULL);
     2555  assert (tabCount > 0);
     2556
     2557  if (tr_torrentRef (tor))
     2558    {
     2559      memset (tab, 0, tabCount);
     2560
     2561      if (tr_torrentHasMetadata (tor))
    25702562        {
    2571             const int piece = i * interval;
    2572 
    2573             if (isSeed || tr_cpPieceIsComplete (&tor->completion, piece))
    2574                 tab[i] = -1;
    2575             else if (peerCount) {
    2576                 int j;
    2577                 for (j=0; j<peerCount; ++j)
     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)
     2570            {
     2571              const int piece = i * interval;
     2572
     2573              if (isSeed || tr_cpPieceIsComplete (&tor->completion, piece))
     2574                {
     2575                  tab[i] = -1;
     2576                }
     2577              else if (peerCount)
     2578                {
     2579                  int j;
     2580                  for (j=0; j<peerCount; ++j)
    25782581                    if (tr_bitfieldHas (&peers[j]->have, piece))
    2579                         ++tab[i];
     2582                      ++tab[i];
     2583                }
    25802584            }
    25812585        }
     2586
     2587      tr_torrentUnref (tor);
    25822588    }
    25832589}
     
    26442650                        int         * setmePeersFrom)
    26452651{
    2646     int i, size;
    2647     const Torrent * t = tor->torrentPeers;
    2648     const tr_peer ** peers;
    2649 
    2650     assert (tr_torrentIsLocked (tor));
    2651 
    2652     peers = (const tr_peer **) tr_ptrArrayBase (&t->peers);
    2653     size = tr_ptrArraySize (&t->peers);
    2654 
    2655     *setmePeersConnected       = 0;
    2656     *setmePeersGettingFromUs   = 0;
    2657     *setmePeersSendingToUs     = 0;
    2658     *setmeWebseedsSendingToUs  = 0;
    2659 
    2660     for (i=0; i<TR_PEER_FROM__MAX; ++i)
     2652  *setmePeersConnected       = 0;
     2653  *setmePeersGettingFromUs   = 0;
     2654  *setmePeersSendingToUs     = 0;
     2655  *setmeWebseedsSendingToUs  = 0;
     2656
     2657  if (tr_torrentRef (tor))
     2658    {
     2659      int i;
     2660      const Torrent * t = tor->torrentPeers;
     2661      const int size = tr_ptrArraySize (&t->peers);
     2662      const tr_peer ** peers = (const tr_peer **) tr_ptrArrayBase (&t->peers);
     2663
     2664      for (i=0; i<TR_PEER_FROM__MAX; ++i)
    26612665        setmePeersFrom[i] = 0;
    26622666
    2663     for (i=0; i<size; ++i)
    2664     {
    2665         const tr_peer * peer = peers[i];
    2666         const struct peer_atom * atom = peer->atom;
    2667 
    2668         if (peer->io == NULL) /* not connected */
     2667      for (i=0; i<size; ++i)
     2668        {
     2669          const tr_peer * peer = peers[i];
     2670          const struct peer_atom * atom = peer->atom;
     2671
     2672          if (peer->io == NULL) /* not connected */
    26692673            continue;
    26702674
    2671         ++*setmePeersConnected;
    2672 
    2673         ++setmePeersFrom[atom->fromFirst];
    2674 
    2675         if (clientIsDownloadingFrom (tor, peer))
     2675          ++*setmePeersConnected;
     2676
     2677          ++setmePeersFrom[atom->fromFirst];
     2678
     2679          if (clientIsDownloadingFrom (tor, peer))
    26762680            ++*setmePeersSendingToUs;
    26772681
    2678         if (clientIsUploadingTo (peer))
     2682          if (clientIsUploadingTo (peer))
    26792683            ++*setmePeersGettingFromUs;
    2680     }
    2681 
    2682     *setmeWebseedsSendingToUs = countActiveWebseeds (t);
     2684        }
     2685
     2686      *setmeWebseedsSendingToUs = countActiveWebseeds (t);
     2687      tr_torrentUnref (tor);
     2688    }
    26832689}
    26842690
    26852691double*
    2686 tr_peerMgrWebSpeeds_KBps (const tr_torrent * tor)
    2687 {
    2688     int i;
    2689     const Torrent * t = tor->torrentPeers;
    2690     const int webseedCount = tr_ptrArraySize (&t->webseeds);
    2691     const tr_webseed ** webseeds = (const tr_webseed**) tr_ptrArrayBase (&t->webseeds);
    2692     const uint64_t now = tr_time_msec ();
    2693     double * ret = tr_new0 (double, webseedCount);
    2694 
    2695     assert (tr_isTorrent (tor));
    2696     assert (tr_torrentIsLocked (tor));
    2697     assert (t->manager != NULL);
    2698     assert (webseedCount == tor->info.webseedCount);
    2699 
    2700     for (i=0; i<webseedCount; ++i) {
    2701         unsigned int Bps;
    2702         if (tr_webseedGetSpeed_Bps (webseeds[i], now, &Bps))
     2692tr_peerMgrWebSpeeds_KBps (tr_torrent * tor)
     2693{
     2694  double * ret = NULL;
     2695
     2696  if (tr_torrentRef (tor))
     2697    {
     2698      int i;
     2699      const Torrent * t = tor->torrentPeers;
     2700      const int webseedCount = tr_ptrArraySize (&t->webseeds);
     2701      const tr_webseed ** webseeds = (const tr_webseed**) tr_ptrArrayBase (&t->webseeds);
     2702      const uint64_t now = tr_time_msec ();
     2703
     2704      ret = tr_new0 (double, webseedCount);
     2705
     2706      assert (t->manager != NULL);
     2707      assert (webseedCount == tor->info.webseedCount);
     2708
     2709      for (i=0; i<webseedCount; ++i)
     2710        {
     2711          unsigned int Bps;
     2712          if (tr_webseedGetSpeed_Bps (webseeds[i], now, &Bps))
    27032713            ret[i] = Bps / (double)tr_speed_K;
    2704         else
     2714          else
    27052715            ret[i] = -1.0;
    2706     }
    2707 
    2708     return ret;
     2716        }
     2717
     2718      tr_torrentUnref (tor);
     2719    }
     2720
     2721  return ret;
    27092722}
    27102723
     
    27162729
    27172730struct tr_peer_stat *
    2718 tr_peerMgrPeerStats (const tr_torrent * tor, int * setmeCount)
    2719 {
    2720     int i;
    2721     const Torrent * t = tor->torrentPeers;
    2722     const int size = tr_ptrArraySize (&t->peers);
    2723     const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase (&t->peers);
    2724     const uint64_t now_msec = tr_time_msec ();
    2725     const time_t now = tr_time ();
    2726     tr_peer_stat * ret = tr_new0 (tr_peer_stat, size);
    2727 
    2728     assert (tr_isTorrent (tor));
    2729     assert (tr_torrentIsLocked (tor));
    2730     assert (t->manager);
    2731 
    2732     for (i=0; i<size; ++i)
    2733     {
    2734         char *                   pch;
    2735         const tr_peer *          peer = peers[i];
    2736         const struct peer_atom * atom = peer->atom;
    2737         tr_peer_stat *           stat = ret + i;
    2738 
    2739         tr_address_to_string_with_buf (&atom->addr, stat->addr, sizeof (stat->addr));
    2740         tr_strlcpy (stat->client, (peer->client ? peer->client : ""),
    2741                    sizeof (stat->client));
    2742         stat->port                = ntohs (peer->atom->port);
    2743         stat->from                = atom->fromFirst;
    2744         stat->progress            = peer->progress;
    2745         stat->isUTP               = peer->io->utp_socket != NULL;
    2746         stat->isEncrypted         = tr_peerIoIsEncrypted (peer->io) ? 1 : 0;
    2747         stat->rateToPeer_KBps     = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_CLIENT_TO_PEER));
    2748         stat->rateToClient_KBps   = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_PEER_TO_CLIENT));
    2749         stat->peerIsChoked        = peer->peerIsChoked;
    2750         stat->peerIsInterested    = peer->peerIsInterested;
    2751         stat->clientIsChoked      = peer->clientIsChoked;
    2752         stat->clientIsInterested  = peer->clientIsInterested;
    2753         stat->isIncoming          = tr_peerIoIsIncoming (peer->io);
    2754         stat->isDownloadingFrom   = clientIsDownloadingFrom (tor, peer);
    2755         stat->isUploadingTo       = clientIsUploadingTo (peer);
    2756         stat->isSeed              = peerIsSeed (peer);
    2757 
    2758         stat->blocksToPeer        = tr_historyGet (&peer->blocksSentToPeer,    now, CANCEL_HISTORY_SEC);
    2759         stat->blocksToClient      = tr_historyGet (&peer->blocksSentToClient,  now, CANCEL_HISTORY_SEC);
    2760         stat->cancelsToPeer       = tr_historyGet (&peer->cancelsSentToPeer,   now, CANCEL_HISTORY_SEC);
    2761         stat->cancelsToClient     = tr_historyGet (&peer->cancelsSentToClient, now, CANCEL_HISTORY_SEC);
    2762 
    2763         stat->pendingReqsToPeer   = peer->pendingReqsToPeer;
    2764         stat->pendingReqsToClient = peer->pendingReqsToClient;
    2765 
    2766         pch = stat->flagStr;
    2767         if (stat->isUTP) *pch++ = 'T';
    2768         if (t->optimistic == peer) *pch++ = 'O';
    2769         if (stat->isDownloadingFrom) *pch++ = 'D';
    2770         else if (stat->clientIsInterested) *pch++ = 'd';
    2771         if (stat->isUploadingTo) *pch++ = 'U';
    2772         else if (stat->peerIsInterested) *pch++ = 'u';
    2773         if (!stat->clientIsChoked && !stat->clientIsInterested) *pch++ = 'K';
    2774         if (!stat->peerIsChoked && !stat->peerIsInterested) *pch++ = '?';
    2775         if (stat->isEncrypted) *pch++ = 'E';
    2776         if (stat->from == TR_PEER_FROM_DHT) *pch++ = 'H';
    2777         else if (stat->from == TR_PEER_FROM_PEX) *pch++ = 'X';
    2778         if (stat->isIncoming) *pch++ = 'I';
    2779         *pch = '\0';
    2780     }
    2781 
    2782     *setmeCount = size;
    2783 
    2784     return ret;
     2731tr_peerMgrPeerStats (tr_torrent * tor, int * setmeCount)
     2732{
     2733  int size = 0;
     2734  tr_peer_stat * ret = NULL;
     2735
     2736  if (tr_torrentRef (tor))
     2737    {
     2738      int i;
     2739      const Torrent * t = tor->torrentPeers;
     2740      const tr_peer ** peers = (const tr_peer**) tr_ptrArrayBase (&t->peers);
     2741      const uint64_t now_msec = tr_time_msec ();
     2742      const time_t now = tr_time ();
     2743
     2744      assert (t->manager != NULL);
     2745
     2746      size = tr_ptrArraySize (&t->peers);
     2747      ret = tr_new0 (tr_peer_stat, size);
     2748
     2749      for (i=0; i<size; ++i)
     2750        {
     2751          char *                   pch;
     2752          const tr_peer *          peer = peers[i];
     2753          const struct peer_atom * atom = peer->atom;
     2754          tr_peer_stat *           stat = ret + i;
     2755
     2756          tr_address_to_string_with_buf (&atom->addr, stat->addr, sizeof (stat->addr));
     2757          tr_strlcpy (stat->client, (peer->client ? peer->client : ""), sizeof (stat->client));
     2758          stat->port                = ntohs (peer->atom->port);
     2759          stat->from                = atom->fromFirst;
     2760          stat->progress            = peer->progress;
     2761          stat->isUTP               = peer->io->utp_socket != NULL;
     2762          stat->isEncrypted         = tr_peerIoIsEncrypted (peer->io) ? 1 : 0;
     2763          stat->rateToPeer_KBps     = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_CLIENT_TO_PEER));
     2764          stat->rateToClient_KBps   = toSpeedKBps (tr_peerGetPieceSpeed_Bps (peer, now_msec, TR_PEER_TO_CLIENT));
     2765          stat->peerIsChoked        = peer->peerIsChoked;
     2766          stat->peerIsInterested    = peer->peerIsInterested;
     2767          stat->clientIsChoked      = peer->clientIsChoked;
     2768          stat->clientIsInterested  = peer->clientIsInterested;
     2769          stat->isIncoming          = tr_peerIoIsIncoming (peer->io);
     2770          stat->isDownloadingFrom   = clientIsDownloadingFrom (tor, peer);
     2771          stat->isUploadingTo       = clientIsUploadingTo (peer);
     2772          stat->isSeed              = peerIsSeed (peer);
     2773
     2774          stat->blocksToPeer        = tr_historyGet (&peer->blocksSentToPeer,    now, CANCEL_HISTORY_SEC);
     2775          stat->blocksToClient      = tr_historyGet (&peer->blocksSentToClient,  now, CANCEL_HISTORY_SEC);
     2776          stat->cancelsToPeer       = tr_historyGet (&peer->cancelsSentToPeer,   now, CANCEL_HISTORY_SEC);
     2777          stat->cancelsToClient     = tr_historyGet (&peer->cancelsSentToClient, now, CANCEL_HISTORY_SEC);
     2778
     2779          stat->pendingReqsToPeer   = peer->pendingReqsToPeer;
     2780          stat->pendingReqsToClient = peer->pendingReqsToClient;
     2781
     2782          pch = stat->flagStr;
     2783          if (stat->isUTP) *pch++ = 'T';
     2784          if (t->optimistic == peer) *pch++ = 'O';
     2785          if (stat->isDownloadingFrom) *pch++ = 'D';
     2786          else if (stat->clientIsInterested) *pch++ = 'd';
     2787          if (stat->isUploadingTo) *pch++ = 'U';
     2788          else if (stat->peerIsInterested) *pch++ = 'u';
     2789          if (!stat->clientIsChoked && !stat->clientIsInterested) *pch++ = 'K';
     2790          if (!stat->peerIsChoked && !stat->peerIsInterested) *pch++ = '?';
     2791          if (stat->isEncrypted) *pch++ = 'E';
     2792          if (stat->from == TR_PEER_FROM_DHT) *pch++ = 'H';
     2793          else if (stat->from == TR_PEER_FROM_PEX) *pch++ = 'X';
     2794          if (stat->isIncoming) *pch++ = 'I';
     2795          *pch = '\0';
     2796        }
     2797
     2798      tr_torrentUnref (tor);
     2799    }
     2800
     2801  *setmeCount = size;
     2802  return ret;
    27852803}
    27862804
     
    28092827/* does this peer have any pieces that we want? */
    28102828static bool
    2811 isPeerInteresting (const tr_torrent  * const tor,
    2812                    const bool        * const piece_is_interesting,
    2813                    const tr_peer     * const peer)
    2814 {
    2815     tr_piece_index_t i, n;
    2816 
    2817     /* these cases should have already been handled by the calling code... */
    2818     assert (!tr_torrentIsSeed (tor));
    2819     assert (tr_torrentIsPieceTransferAllowed (tor, TR_PEER_TO_CLIENT));
    2820 
    2821     if (peerIsSeed (peer))
    2822         return true;
    2823 
    2824     for (i=0, n=tor->info.pieceCount; i<n; ++i)
    2825         if (piece_is_interesting[i] && tr_bitfieldHas (&peer->have, i))
    2826             return true;
    2827 
    2828     return false;
     2829isPeerInteresting (tr_torrent     * const tor,
     2830                   const bool     * const piece_is_interesting,
     2831                   const tr_peer  * const peer)
     2832{
     2833  tr_piece_index_t i, n;
     2834
     2835  /* these cases should have already been handled by the calling code... */
     2836  assert (!tr_torrentIsSeed (tor));
     2837  assert (tr_torrentIsPieceTransferAllowed (tor, TR_PEER_TO_CLIENT));
     2838
     2839  if (peerIsSeed (peer))
     2840    return true;
     2841
     2842  for (i=0, n=tor->info.pieceCount; i<n; ++i)
     2843    if (piece_is_interesting[i] && tr_bitfieldHas (&peer->have, i))
     2844      return true;
     2845
     2846  return false;
    28292847}
    28302848
Note: See TracChangeset for help on using the changeset viewer.