Ignore:
Timestamp:
Jan 12, 2006, 7:12:58 PM (16 years ago)
Author:
root
Message:

Update 2006-01-11

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/transmission.c

    r23 r26  
    3030static float rateDownload( tr_torrent_t * );
    3131static float rateUpload( tr_torrent_t * );
     32static void  acceptLoop( void * );
     33static void acceptStop( tr_handle_t * h );
    3234
    3335/***********************************************************************
     
    6870
    6971    h->bindPort = TR_DEFAULT_PORT;
     72    h->bindSocket = -1;
     73
     74#ifndef BEOS_NETSERVER
     75    /* BeOS net_server seems to be unable to set incoming connections to
     76       non-blocking. Too bad. */
     77    if( !tr_fdSocketWillCreate( h->fdlimit, 0 ) )
     78    {
     79        /* XXX should handle failure here in a better way */
     80        h->bindSocket = tr_netBind( h->bindPort );
     81    }
     82#endif
     83
     84
     85    h->acceptDie = 0;
     86    tr_lockInit( &h->acceptLock );
     87    tr_threadCreate( &h->acceptThread, acceptLoop, h );
    7088
    7189    return h;
     
    7997void tr_setBindPort( tr_handle_t * h, int port )
    8098{
    81     /* FIXME multithread safety */
     99    int ii, sock;
     100
     101    if( h->bindPort == port )
     102      return;
     103
     104#ifndef BEOS_NETSERVER
     105    /* BeOS net_server seems to be unable to set incoming connections to
     106       non-blocking. Too bad. */
     107    if( !tr_fdSocketWillCreate( h->fdlimit, 0 ) )
     108    {
     109        /* XXX should handle failure here in a better way */
     110        sock = tr_netBind( port );
     111    }
     112#else
     113    return;
     114#endif
     115
     116    tr_lockLock( &h->acceptLock );
     117
    82118    h->bindPort = port;
     119
     120    for( ii = 0; ii < h->torrentCount; ii++ )
     121    {
     122        tr_lockLock( &h->torrents[ii]->lock );
     123        if( NULL != h->torrents[ii]->tracker )
     124        {
     125            tr_trackerChangePort( h->torrents[ii]->tracker, port );
     126        }
     127        tr_lockUnlock( &h->torrents[ii]->lock );
     128    }
     129
     130    if( h->bindSocket > -1 )
     131    {
     132        tr_netClose( h->bindSocket );
     133        tr_fdSocketClosed( h->fdlimit, 0 );
     134    }
     135
     136    h->bindSocket = sock;
     137
     138    tr_lockUnlock( &h->acceptLock );
    83139}
    84140
     
    197253 
    198254    /* We have a new torrent */
     255    tr_lockLock( &h->acceptLock );
    199256    h->torrents[h->torrentCount] = tor;
    200257    (h->torrentCount)++;
     258    tr_lockUnlock( &h->acceptLock );
    201259
    202260    return 0;
     
    242300    tor->status   = TR_STATUS_CHECK;
    243301    tor->tracker  = tr_trackerInit( h, tor );
    244     tor->bindPort = h->bindPort;
    245 #ifndef BEOS_NETSERVER
    246     /* BeOS net_server seems to be unable to set incoming connections to
    247        non-blocking. Too bad. */
    248     if( !tr_fdSocketWillCreate( h->fdlimit, 0 ) )
    249     {
    250         tor->bindSocket = tr_netBind( &tor->bindPort );
    251     }
    252 #endif
    253302
    254303    now = tr_date();
     
    291340    {
    292341        tr_peerRem( tor, 0 );
    293     }
    294     if( tor->bindSocket > -1 )
    295     {
    296         tr_netClose( tor->bindSocket );
    297         tr_fdSocketClosed( h->fdlimit, 0 );
    298342    }
    299343
     
    446490    }
    447491
     492    tr_lockLock( &h->acceptLock );
     493
    448494    h->torrentCount--;
    449495
     
    461507    memmove( &h->torrents[t], &h->torrents[t+1],
    462508             ( h->torrentCount - t ) * sizeof( void * ) );
     509
     510    tr_lockUnlock( &h->acceptLock );
    463511}
    464512
    465513void tr_close( tr_handle_t * h )
    466514{
     515    acceptStop( h );
    467516    tr_fdClose( h->fdlimit );
    468517    tr_uploadClose( h->upload );
     
    568617    return rateGeneric( tor->dates, tor->uploaded );
    569618}
     619
     620/***********************************************************************
     621 * acceptLoop
     622 **********************************************************************/
     623static void acceptLoop( void * _h )
     624{
     625    tr_handle_t * h = _h;
     626    uint64_t      date1, date2;
     627    int           ii, jj;
     628    uint8_t     * hash;
     629
     630    tr_dbg( "Accept thread started" );
     631
     632#ifdef SYS_BEOS
     633    /* This is required because on BeOS, SIGINT is sent to each thread,
     634       which kills them not nicely */
     635    signal( SIGINT, SIG_IGN );
     636#endif
     637
     638    tr_lockLock( &h->acceptLock );
     639
     640    while( !h->acceptDie )
     641    {
     642        date1 = tr_date();
     643
     644        /* Check for incoming connections */
     645        if( h->bindSocket > -1 &&
     646            h->acceptPeerCount < TR_MAX_PEER_COUNT &&
     647            !tr_fdSocketWillCreate( h->fdlimit, 0 ) )
     648        {
     649            int            s;
     650            struct in_addr addr;
     651            in_port_t      port;
     652            s = tr_netAccept( h->bindSocket, &addr, &port );
     653            if( s > -1 )
     654            {
     655                h->acceptPeers[h->acceptPeerCount++] = tr_peerInit( addr, port, s );
     656            }
     657            else
     658            {
     659                tr_fdSocketClosed( h->fdlimit, 0 );
     660            }
     661        }
     662
     663        for( ii = 0; ii < h->acceptPeerCount; )
     664        {
     665            if( tr_peerRead( NULL, h->acceptPeers[ii] ) )
     666            {
     667                tr_peerDestroy( h->fdlimit, h->acceptPeers[ii] );
     668                goto removePeer;
     669            }
     670            if( NULL != ( hash = tr_peerHash( h->acceptPeers[ii] ) ) )
     671            {
     672                for( jj = 0; jj < h->torrentCount; jj++ )
     673                {
     674                    tr_lockLock( &h->torrents[jj]->lock );
     675                    if( 0 == memcmp( h->torrents[jj]->info.hash, hash,
     676                                     SHA_DIGEST_LENGTH ) )
     677                    {
     678                      tr_peerAttach( h->torrents[jj], h->acceptPeers[ii] );
     679                      tr_lockUnlock( &h->torrents[jj]->lock );
     680                      goto removePeer;
     681                    }
     682                    tr_lockUnlock( &h->torrents[jj]->lock );
     683                }
     684                tr_peerDestroy( h->fdlimit, h->acceptPeers[ii] );
     685                goto removePeer;
     686            }
     687            ii++;
     688            continue;
     689           removePeer:
     690            h->acceptPeerCount--;
     691            memmove( &h->acceptPeers[ii], &h->acceptPeers[ii+1],
     692                     ( h->acceptPeerCount - ii ) * sizeof( tr_peer_t * ) );
     693        }
     694
     695        /* Wait up to 20 ms */
     696        date2 = tr_date();
     697        if( date2 < date1 + 20 )
     698        {
     699            tr_lockUnlock( &h->acceptLock );
     700            tr_wait( date1 + 20 - date2 );
     701            tr_lockLock( &h->acceptLock );
     702        }
     703    }
     704
     705    tr_lockUnlock( &h->acceptLock );
     706
     707    tr_dbg( "Accept thread exited" );
     708}
     709
     710/***********************************************************************
     711 * acceptStop
     712 ***********************************************************************
     713 * Joins the accept thread and frees/closes everything related to it.
     714 **********************************************************************/
     715static void acceptStop( tr_handle_t * h )
     716{
     717    int ii;
     718
     719    h->acceptDie = 1;
     720    tr_threadJoin( &h->acceptThread );
     721    tr_lockClose( &h->acceptLock );
     722    tr_dbg( "Accept thread joined" );
     723
     724    for( ii = 0; ii < h->acceptPeerCount; ii++ )
     725    {
     726        tr_peerDestroy( h->fdlimit, h->acceptPeers[ii] );
     727    }
     728
     729    if( h->bindSocket > -1 )
     730    {
     731        tr_netClose( h->bindSocket );
     732        tr_fdSocketClosed( h->fdlimit, 0 );
     733    }
     734}
Note: See TracChangeset for help on using the changeset viewer.