Ignore:
Timestamp:
Dec 20, 2010, 2:07:51 AM (11 years ago)
Author:
charles
Message:

(trunk) #3836 "libevent2 support" -- bump libevent2 requirement to 2.0.10. This will break the Mac build for a minute intil BMW applies his Mac patch

File:
1 edited

Legend:

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

    r11398 r11548  
    2424#endif
    2525
    26 #include <event.h>
     26#include <event2/event.h>
     27#include <event2/bufferevent.h>
    2728
    2829#include "transmission.h"
     
    144145        {
    145146            size_t piece = 0;
    146             const size_t oldLen = EVBUFFER_LENGTH( io->inbuf );
     147            const size_t oldLen = evbuffer_get_length( io->inbuf );
    147148            const int ret = io->canRead( io, io->userData, &piece );
    148149
    149             const size_t used = oldLen - EVBUFFER_LENGTH( io->inbuf );
     150            const size_t used = oldLen - evbuffer_get_length( io->inbuf );
    150151
    151152            assert( tr_isPeerIo( io ) );
     
    165166            {
    166167                case READ_NOW:
    167                     if( EVBUFFER_LENGTH( io->inbuf ) )
     168                    if( evbuffer_get_length( io->inbuf ) )
    168169                        continue;
    169170                    done = 1;
     
    183184
    184185        tr_sessionUnlock( session );
    185     }
    186 
    187     /* keep the iobuf's excess capacity from growing too large */
    188     if( EVBUFFER_LENGTH( io->inbuf ) == 0 ) {
    189         evbuffer_free( io->inbuf );
    190         io->inbuf = evbuffer_new( );
    191186    }
    192187
     
    223218    io->pendingEvents &= ~EV_READ;
    224219
    225     curlen = EVBUFFER_LENGTH( io->inbuf );
     220    curlen = evbuffer_get_length( io->inbuf );
    226221    howmuch = curlen >= max ? 0 : max - curlen;
    227222    howmuch = tr_bandwidthClamp( &io->bandwidth, TR_DOWN, howmuch );
     
    249244    {
    250245        char errstr[512];
    251         short what = EVBUFFER_READ;
     246        short what = BEV_EVENT_READING;
    252247
    253248        if( res == 0 ) /* EOF */
    254             what |= EVBUFFER_EOF;
     249            what |= BEV_EVENT_EOF;
    255250        else if( res == -1 ) {
    256251            if( e == EAGAIN || e == EINTR ) {
     
    258253                return;
    259254            }
    260             what |= EVBUFFER_ERROR;
     255            what |= BEV_EVENT_ERROR;
    261256        }
    262257
     
    275270    int n;
    276271    char errstr[256];
    277     struct evbuffer * buffer = io->outbuf;
    278 
    279     howmuch = MIN( EVBUFFER_LENGTH( buffer ), howmuch );
     272    const size_t len = evbuffer_get_length( io->outbuf );
     273    const int vecCount = evbuffer_peek( io->outbuf, len, NULL, NULL, 0 );
    280274
    281275    EVUTIL_SET_SOCKET_ERROR( 0 );
    282 #ifdef WIN32
    283     n = (int) send(fd, buffer->buffer, howmuch,  0 );
    284 #else
    285     n = (int) write(fd, buffer->buffer, howmuch );
    286 #endif
     276    n = evbuffer_write_atmost( io->outbuf, fd, howmuch );
    287277    e = EVUTIL_SOCKET_ERROR( );
    288278    dbgmsg( io, "wrote %d to peer (%s)", n, (n==-1?tr_net_strerror(errstr,sizeof(errstr),e):"") );
    289279
    290     if( n > 0 )
    291         evbuffer_drain( buffer, (size_t)n );
    292 
    293     /* keep the iobuf's excess capacity from growing too large */
    294     if( EVBUFFER_LENGTH( io->outbuf ) == 0 ) {
    295         evbuffer_free( io->outbuf );
    296         io->outbuf = evbuffer_new( );
    297     }
    298 
    299280    return n;
    300281}
     
    305286    int res = 0;
    306287    int e;
    307     short what = EVBUFFER_WRITE;
     288    short what = BEV_EVENT_WRITING;
    308289    tr_peerIo * io = vio;
    309290    size_t howmuch;
     
    319300    /* Write as much as possible, since the socket is non-blocking, write() will
    320301     * return if it can't write any more data without blocking */
    321     howmuch = tr_bandwidthClamp( &io->bandwidth, dir, EVBUFFER_LENGTH( io->outbuf ) );
     302    howmuch = tr_bandwidthClamp( &io->bandwidth, dir, evbuffer_get_length( io->outbuf ) );
    322303
    323304    /* if we don't have any bandwidth left, stop writing */
     
    332313
    333314    if (res == -1) {
    334         if (e == EAGAIN || e == EINTR || e == EINPROGRESS)
     315        if (!e || e == EAGAIN || e == EINTR || e == EINPROGRESS)
    335316            goto reschedule;
    336317        /* error case */
    337         what |= EVBUFFER_ERROR;
     318        what |= BEV_EVENT_ERROR;
    338319    } else if (res == 0) {
    339320        /* eof case */
    340         what |= EVBUFFER_EOF;
     321        what |= BEV_EVENT_EOF;
    341322    }
    342323    if (res <= 0)
    343324        goto error;
    344325
    345     if( EVBUFFER_LENGTH( io->outbuf ) )
     326    if( evbuffer_get_length( io->outbuf ) )
    346327        tr_peerIoSetEnabled( io, dir, TRUE );
    347328
     
    350331
    351332 reschedule:
    352     if( EVBUFFER_LENGTH( io->outbuf ) )
     333    if( evbuffer_get_length( io->outbuf ) )
    353334        tr_peerIoSetEnabled( io, dir, TRUE );
    354335    return;
     
    416397    io->inbuf = evbuffer_new( );
    417398    io->outbuf = evbuffer_new( );
     399    io->event_read = event_new( NULL, io->socket, EV_READ, event_read_cb, io );
     400    io->event_write = event_new( NULL, io->socket, EV_WRITE, event_write_cb, io );
    418401    tr_bandwidthConstruct( &io->bandwidth, session, parent );
    419402    tr_bandwidthSetPeer( &io->bandwidth, io );
    420403    dbgmsg( io, "bandwidth is %p; its parent is %p", &io->bandwidth, parent );
    421 
    422     event_set( &io->event_read, io->socket, EV_READ, event_read_cb, io );
    423     event_set( &io->event_write, io->socket, EV_WRITE, event_write_cb, io );
    424404
    425405    return io;
     
    471451    assert( io->session != NULL );
    472452    assert( io->session->events != NULL );
    473     assert( event_initialized( &io->event_read ) );
    474     assert( event_initialized( &io->event_write ) );
     453    assert( event_initialized( io->event_read ) );
     454    assert( event_initialized( io->event_write ) );
    475455
    476456    if( io->socket < 0 )
     
    480460    {
    481461        dbgmsg( io, "enabling libevent ready-to-read polling" );
    482         event_add( &io->event_read, NULL );
     462        event_add( io->event_read, NULL );
    483463        io->pendingEvents |= EV_READ;
    484464    }
     
    487467    {
    488468        dbgmsg( io, "enabling libevent ready-to-write polling" );
    489         event_add( &io->event_write, NULL );
     469        event_add( io->event_write, NULL );
    490470        io->pendingEvents |= EV_WRITE;
    491471    }
     
    498478    assert( io->session != NULL );
    499479    assert( io->session->events != NULL );
    500     assert( event_initialized( &io->event_read ) );
    501     assert( event_initialized( &io->event_write ) );
     480    assert( event_initialized( io->event_read ) );
     481    assert( event_initialized( io->event_write ) );
    502482
    503483    if( ( event & EV_READ ) && ( io->pendingEvents & EV_READ ) )
    504484    {
    505485        dbgmsg( io, "disabling libevent ready-to-read polling" );
    506         event_del( &io->event_read );
     486        event_del( io->event_read );
    507487        io->pendingEvents &= ~EV_READ;
    508488    }
     
    511491    {
    512492        dbgmsg( io, "disabling libevent ready-to-write polling" );
    513         event_del( &io->event_write );
     493        event_del( io->event_write );
    514494        io->pendingEvents &= ~EV_WRITE;
    515495    }
     
    549529    dbgmsg( io, "in tr_peerIo destructor" );
    550530    event_disable( io, EV_READ | EV_WRITE );
     531    event_free( io->event_read );
     532    event_free( io->event_write );
    551533    tr_bandwidthDestruct( &io->bandwidth );
    552534    evbuffer_free( io->outbuf );
     
    662644        tr_netClose( session, io->socket );
    663645
     646    event_del( io->event_read );
     647    event_del( io->event_write );
    664648    io->socket = tr_netOpenPeerSocket( session, &io->addr, io->port, io->isSeed );
    665     event_set( &io->event_read, io->socket, EV_READ, event_read_cb, io );
    666     event_set( &io->event_write, io->socket, EV_WRITE, event_write_cb, io );
     649    io->event_read = event_new( NULL, io->socket, EV_READ, event_read_cb, io );
     650    io->event_write = event_new( NULL, io->socket, EV_WRITE, event_write_cb, io );
    667651
    668652    if( io->socket >= 0 )
     
    746730{
    747731    const size_t desiredLen = getDesiredOutputBufferSize( io, now );
    748     const size_t currentLen = EVBUFFER_LENGTH( io->outbuf );
     732    const size_t currentLen = evbuffer_get_length( io->outbuf );
    749733    size_t freeSpace = 0;
    750734
     
    773757**/
    774758
    775 void
    776 tr_peerIoWrite( tr_peerIo   * io,
    777                 const void  * bytes,
    778                 size_t        byteCount,
    779                 tr_bool       isPieceData )
    780 {
    781     /* FIXME(libevent2): this implementation snould be moved to tr_peerIoWriteBuf.   This function should be implemented as evbuffer_new() + evbuffer_add_reference() + a call to tr_peerIoWriteBuf() + evbuffer_free() */
    782     struct tr_datatype * datatype;
    783 
    784     assert( tr_amInEventThread( io->session ) );
    785     dbgmsg( io, "adding %zu bytes into io->output", byteCount );
    786 
    787     datatype = tr_new( struct tr_datatype, 1 );
    788     datatype->isPieceData = isPieceData != 0;
    789     datatype->length = byteCount;
    790     tr_list_append( &io->outbuf_datatypes, datatype );
    791 
    792     switch( io->encryptionMode )
    793     {
    794         case PEER_ENCRYPTION_RC4:
    795         {
    796             /* FIXME(libevent2): use evbuffer_reserve_space() and evbuffer_commit_space() instead of tmp */
    797             void * tmp = tr_sessionGetBuffer( io->session );
    798             const size_t tmplen = SESSION_BUFFER_SIZE;
    799             const uint8_t * walk = bytes;
    800             evbuffer_expand( io->outbuf, byteCount );
    801             while( byteCount > 0 )
    802             {
    803                 const size_t thisPass = MIN( byteCount, tmplen );
    804                 tr_cryptoEncrypt( io->crypto, thisPass, walk, tmp );
    805                 evbuffer_add( io->outbuf, tmp, thisPass );
    806                 walk += thisPass;
    807                 byteCount -= thisPass;
    808             }
    809             tr_sessionReleaseBuffer( io->session );
    810             break;
    811         }
    812 
    813         case PEER_ENCRYPTION_NONE:
    814             evbuffer_add( io->outbuf, bytes, byteCount );
    815             break;
    816 
    817         default:
    818             assert( 0 );
    819             break;
    820     }
    821 }
    822 
    823 void
    824 tr_peerIoWriteBuf( tr_peerIo         * io,
    825                    struct evbuffer   * buf,
    826                    tr_bool             isPieceData )
    827 {
    828     /* FIXME(libevent2): loop through calls to evbuffer_get_contiguous_space() + evbuffer_drain() */
    829     const size_t n = EVBUFFER_LENGTH( buf );
    830     tr_peerIoWrite( io, EVBUFFER_DATA( buf ), n, isPieceData );
    831     evbuffer_drain( buf, n );
    832 }
    833 
    834 void
    835 tr_peerIoWriteUint16( tr_peerIo        * io,
    836                       struct evbuffer  * outbuf,
    837                       uint16_t           writeme )
    838 {
    839     const uint16_t tmp = htons( writeme );
    840     tr_peerIoWriteBytes( io, outbuf, &tmp, sizeof( uint16_t ) );
    841 }
    842 
    843 void
    844 tr_peerIoWriteUint32( tr_peerIo        * io,
    845                       struct evbuffer  * outbuf,
    846                       uint32_t           writeme )
    847 {
    848     const uint32_t tmp = htonl( writeme );
    849     tr_peerIoWriteBytes( io, outbuf, &tmp, sizeof( uint32_t ) );
     759static void
     760addDatatype( tr_peerIo * io, size_t byteCount, tr_bool isPieceData )
     761{
     762    struct tr_datatype * d;
     763
     764    d = tr_new( struct tr_datatype, 1 );
     765    d->isPieceData = isPieceData != 0;
     766    d->length = byteCount;
     767    tr_list_append( &io->outbuf_datatypes, d );
     768}
     769
     770static struct evbuffer_iovec *
     771evbuffer_peek_all( struct evbuffer * buf, size_t * setme_vecCount )
     772{
     773    const size_t byteCount = evbuffer_get_length( buf );
     774    const int vecCount = evbuffer_peek( buf, byteCount, NULL, NULL, 0 );
     775    struct evbuffer_iovec * iovec = tr_new0( struct evbuffer_iovec, vecCount );
     776    const int n = evbuffer_peek( buf, byteCount, NULL, iovec, vecCount );
     777    assert( vecCount == n );
     778    *setme_vecCount = vecCount;
     779    return iovec;
     780}
     781
     782static void
     783maybeEncryptBuffer( tr_peerIo * io, struct evbuffer * buf )
     784{
     785    if( io->encryptionMode == PEER_ENCRYPTION_RC4 )
     786    {
     787        size_t i, n;
     788        struct evbuffer_iovec * iovec = evbuffer_peek_all( buf, &n );
     789
     790        for( i=0; i<n; ++i )
     791            tr_cryptoEncrypt( io->crypto, iovec[i].iov_len, iovec[i].iov_base, iovec[i].iov_base );
     792
     793        tr_free( iovec );
     794    }
     795}
     796
     797void
     798tr_peerIoWriteBuf( tr_peerIo * io, struct evbuffer * buf, tr_bool isPieceData )
     799{
     800    const size_t byteCount = evbuffer_get_length( buf );
     801    maybeEncryptBuffer( io, buf );
     802    evbuffer_add_buffer( io->outbuf, buf );
     803    addDatatype( io, byteCount, isPieceData );
     804}
     805
     806void
     807tr_peerIoWriteBytes( tr_peerIo * io, const void * bytes, size_t byteCount, tr_bool isPieceData )
     808{
     809    struct evbuffer * buf = evbuffer_new( );
     810    evbuffer_add( buf, bytes, byteCount );
     811    tr_peerIoWriteBuf( io, buf, isPieceData );
     812    evbuffer_free( buf );
    850813}
    851814
     
    855818
    856819void
    857 tr_peerIoReadBytes( tr_peerIo       * io,
    858                     struct evbuffer * inbuf,
    859                     void            * bytes,
    860                     size_t            byteCount )
    861 {
    862     assert( tr_isPeerIo( io ) );
    863     /* FIXME(libevent2): use evbuffer_get_length() */
    864     assert( EVBUFFER_LENGTH( inbuf ) >= byteCount );
     820evbuffer_add_uint16( struct evbuffer * outbuf, uint16_t addme_hs )
     821{
     822    const uint16_t ns = htons( addme_hs );
     823    evbuffer_add( outbuf, &ns, sizeof( ns ) );
     824}
     825
     826void
     827evbuffer_add_uint32( struct evbuffer * outbuf, uint32_t addme_hl )
     828{
     829    const uint32_t nl = htonl( addme_hl );
     830    evbuffer_add( outbuf, &nl, sizeof( nl ) );
     831}
     832
     833/***
     834****
     835***/
     836
     837void
     838tr_peerIoReadBytes( tr_peerIo * io, struct evbuffer * inbuf, void * bytes, size_t byteCount )
     839{
     840    assert( tr_isPeerIo( io ) );
     841    assert( evbuffer_get_length( inbuf )  >= byteCount );
    865842
    866843    switch( io->encryptionMode )
     
    871848
    872849        case PEER_ENCRYPTION_RC4:
    873             /* FIXME(libevent2): loop through calls to evbuffer_get_contiguous_space() + evbuffer_drain() */
    874             tr_cryptoDecrypt( io->crypto, byteCount, EVBUFFER_DATA(inbuf), bytes );
    875             evbuffer_drain(inbuf, byteCount );
     850            evbuffer_remove( inbuf, bytes, byteCount );
     851            tr_cryptoDecrypt( io->crypto, byteCount, bytes, bytes );
    876852            break;
    877853
     
    937913        dbgmsg( io, "read %d from peer (%s)", res, (res==-1?strerror(e):"") );
    938914
    939         if( EVBUFFER_LENGTH( io->inbuf ) )
     915        if( evbuffer_get_length( io->inbuf ) )
    940916            canReadWrapper( io );
    941917
     
    943919        {
    944920            char errstr[512];
    945             short what = EVBUFFER_READ | EVBUFFER_ERROR;
     921            short what = BEV_EVENT_READING | BEV_EVENT_ERROR;
    946922            if( res == 0 )
    947                 what |= EVBUFFER_EOF;
     923                what |= BEV_EVENT_EOF;
    948924            tr_net_strerror( errstr, sizeof( errstr ), e );
    949925            dbgmsg( io, "tr_peerIoTryRead got an error. res is %d, what is %hd, errno is %d (%s)", res, what, e, errstr );
     
    970946            didWriteWrapper( io, n );
    971947
    972         if( ( n < 0 ) && ( io->gotError ) && ( e != EPIPE ) && ( e != EAGAIN ) && ( e != EINTR ) && ( e != EINPROGRESS ) )
     948        if( ( n < 0 ) && ( io->gotError ) && e && ( e != EPIPE ) && ( e != EAGAIN ) && ( e != EINTR ) && ( e != EINPROGRESS ) )
    973949        {
    974950            char errstr[512];
    975             const short what = EVBUFFER_WRITE | EVBUFFER_ERROR;
     951            const short what = BEV_EVENT_WRITING | BEV_EVENT_ERROR;
    976952
    977953            tr_net_strerror( errstr, sizeof( errstr ), e );
Note: See TracChangeset for help on using the changeset viewer.