Ignore:
Timestamp:
Jan 17, 2010, 7:21:04 PM (12 years ago)
Author:
charles
Message:

(trunk libT) #2416 "crash in event_queue_insert()" -- this crash is definitely happening when we call event_del() twice on the same event without an event dispatch pass between the two calls. Start nailing down every possible case where that could happen in libtransmission

File:
1 edited

Legend:

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

    r9868 r9959  
    440440}
    441441
     442/***
     443****
     444***/
     445
     446static void
     447event_enable( tr_peerIo * io, short event )
     448{
     449    assert( tr_amInEventThread( io->session ) );
     450    assert( io->session != NULL );
     451    assert( io->session->events != NULL );
     452    assert( event_initialized( &io->event_read ) );
     453    assert( event_initialized( &io->event_write ) );
     454
     455    if( ( event & EV_READ ) && ! ( io->pendingEvents & EV_READ ) )
     456    {
     457        dbgmsg( io, "enabling libevent ready-to-read polling" );
     458        event_add( &io->event_read, NULL );
     459        io->pendingEvents |= EV_READ;
     460    }
     461
     462    if( ( event & EV_WRITE ) && ! ( io->pendingEvents & EV_WRITE ) )
     463    {
     464        dbgmsg( io, "enabling libevent ready-to-write polling" );
     465        event_add( &io->event_write, NULL );
     466        io->pendingEvents |= EV_WRITE;
     467    }
     468}
     469
     470static void
     471event_disable( struct tr_peerIo * io, short event )
     472{
     473    assert( tr_amInEventThread( io->session ) );
     474    assert( io->session != NULL );
     475    assert( io->session->events != NULL );
     476    assert( event_initialized( &io->event_read ) );
     477    assert( event_initialized( &io->event_write ) );
     478
     479    if( ( event & EV_READ ) && ( io->pendingEvents & EV_READ ) )
     480    {
     481        dbgmsg( io, "disabling libevent ready-to-read polling" );
     482        event_del( &io->event_read );
     483        io->pendingEvents &= ~EV_READ;
     484    }
     485
     486    if( ( event & EV_WRITE ) && ( io->pendingEvents & EV_WRITE ) )
     487    {
     488        dbgmsg( io, "disabling libevent ready-to-write polling" );
     489        event_del( &io->event_write );
     490        io->pendingEvents &= ~EV_WRITE;
     491    }
     492}
     493
     494void
     495tr_peerIoSetEnabled( tr_peerIo    * io,
     496                     tr_direction   dir,
     497                     tr_bool        isEnabled )
     498{
     499    const short event = dir == TR_UP ? EV_WRITE : EV_READ;
     500
     501    assert( tr_isPeerIo( io ) );
     502    assert( tr_isDirection( dir ) );
     503    assert( tr_amInEventThread( io->session ) );
     504    assert( io->session->events != NULL );
     505
     506    if( isEnabled )
     507        event_enable( io, event );
     508    else
     509        event_disable( io, event );
     510}
     511
     512/***
     513****
     514***/
     515
    442516static void
    443517trDatatypeFree( void * data )
     
    457531
    458532    dbgmsg( io, "in tr_peerIo destructor" );
    459     event_del( &io->event_read );
    460     event_del( &io->event_write );
     533    event_disable( io, ~0 );
    461534    tr_bandwidthDestruct( &io->bandwidth );
    462535    evbuffer_free( io->outbuf );
     
    553626tr_peerIoReconnect( tr_peerIo * io )
    554627{
     628    int pendingEvents;
    555629    tr_session * session;
    556630
     
    559633
    560634    session = tr_peerIoGetSession( io );
     635
     636    pendingEvents = io->pendingEvents;
     637    event_disable( io, ~0 );
    561638
    562639    if( io->socket >= 0 )
     
    564641
    565642    io->socket = tr_netOpenPeerSocket( session, &io->addr, io->port, io->isSeed );
     643    event_set( &io->event_read, io->socket, EV_READ, event_read_cb, io );
     644    event_set( &io->event_write, io->socket, EV_WRITE, event_write_cb, io );
     645    event_enable( io, pendingEvents );
     646
    566647    if( io->socket >= 0 )
    567648    {
     
    909990    return tr_peerIoFlush( io, TR_UP, byteCount );
    910991}
    911 
    912 
    913 /***
    914 ****
    915 ****/
    916 
    917 static void
    918 event_enable( tr_peerIo * io, short event )
    919 {
    920     assert( tr_amInEventThread( io->session ) );
    921     assert( io->session != NULL );
    922     assert( io->session->events != NULL );
    923     assert( event_initialized( &io->event_read ) );
    924     assert( event_initialized( &io->event_write ) );
    925 
    926     if( ( event & EV_READ ) && ! ( io->pendingEvents & EV_READ ) )
    927     {
    928         dbgmsg( io, "enabling libevent ready-to-read polling" );
    929         event_add( &io->event_read, NULL );
    930         io->pendingEvents |= EV_READ;
    931     }
    932 
    933     if( ( event & EV_WRITE ) && ! ( io->pendingEvents & EV_WRITE ) )
    934     {
    935         dbgmsg( io, "enabling libevent ready-to-write polling" );
    936         event_add( &io->event_write, NULL );
    937         io->pendingEvents |= EV_WRITE;
    938     }
    939 }
    940 
    941 static void
    942 event_disable( struct tr_peerIo * io, short event )
    943 {
    944     assert( tr_amInEventThread( io->session ) );
    945     assert( io->session != NULL );
    946     assert( io->session->events != NULL );
    947     assert( event_initialized( &io->event_read ) );
    948     assert( event_initialized( &io->event_write ) );
    949 
    950     if( ( event & EV_READ ) && ( io->pendingEvents & EV_READ ) )
    951     {
    952         dbgmsg( io, "disabling libevent ready-to-read polling" );
    953         event_del( &io->event_read );
    954         io->pendingEvents &= ~EV_READ;
    955     }
    956 
    957     if( ( event & EV_WRITE ) && ( io->pendingEvents & EV_WRITE ) )
    958     {
    959         dbgmsg( io, "disabling libevent ready-to-write polling" );
    960         event_del( &io->event_write );
    961         io->pendingEvents &= ~EV_WRITE;
    962     }
    963 }
    964 
    965 
    966 void
    967 tr_peerIoSetEnabled( tr_peerIo    * io,
    968                      tr_direction   dir,
    969                      tr_bool        isEnabled )
    970 {
    971     const short event = dir == TR_UP ? EV_WRITE : EV_READ;
    972 
    973     assert( tr_isPeerIo( io ) );
    974     assert( tr_isDirection( dir ) );
    975     assert( tr_amInEventThread( io->session ) );
    976     assert( io->session->events != NULL );
    977 
    978     if( isEnabled )
    979         event_enable( io, event );
    980     else
    981         event_disable( io, event );
    982 }
Note: See TracChangeset for help on using the changeset viewer.