Changeset 9717


Ignore:
Timestamp:
Dec 11, 2009, 3:41:34 PM (12 years ago)
Author:
charles
Message:

(trunk libT) #2416 "crash in event_queue_insert()"

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/web.c

    r9710 r9717  
    2020
    2121#include "transmission.h"
    22 #include "list.h"
    2322#include "net.h" /* socklen_t */
    2423#include "session.h"
     
    5150#endif
    5251
    53 struct tr_web_sockinfo
    54 {
    55     int fd;
    56     tr_bool evset;
    57     struct event ev;
    58 };
    59 
    6052struct tr_web
    6153{
     
    6961    tr_address addr;
    7062    struct event timer_event;
    71     tr_list * fds;
    7263};
    73 
    74 /***
    75 ****
    76 ***/
    77 
    78 static struct tr_web_sockinfo *
    79 getSockinfo( tr_web * web, int fd, tr_bool createIfMissing )
    80 {
    81     tr_list * l;
    82 
    83     for( l=web->fds; l!=NULL; l=l->next ) {
    84         struct tr_web_sockinfo * s =  l->data;
    85         if( s->fd == fd ) {
    86             dbgmsg( "looked up sockinfo %p for fd %d", s, fd );
    87             return s;
    88         }
    89     }
    90 
    91     if( createIfMissing ) {
    92         struct tr_web_sockinfo * s =  tr_new0( struct tr_web_sockinfo, 1 );
    93         s->fd = fd;
    94         tr_list_prepend( &web->fds, s );
    95         dbgmsg( "created sockinfo %p for fd %d... we now have %d sockinfos", s, fd, tr_list_size(web->fds) );
    96         return s;
    97     }
    98 
    99     return NULL;
    100 }
    101 
    102 static void
    103 clearSockinfoEvent( struct tr_web_sockinfo * s )
    104 {
    105     if( s && s->evset )
    106     {
    107         dbgmsg( "clearing libevent polling for sockinfo %p, fd %d", s, s->fd );
    108         event_del( &s->ev );
    109         s->evset = FALSE;
    110     }
    111 }
    112 
    113 static void
    114 purgeSockinfo( tr_web * web, int fd )
    115 {
    116     struct tr_web_sockinfo * s = getSockinfo( web, fd, FALSE );
    117 
    118     if( s != NULL )
    119     {
    120         tr_list_remove_data( &web->fds, s );
    121         clearSockinfoEvent( s );
    122         dbgmsg( "freeing sockinfo %p, fd %d", s, s->fd );
    123         tr_free( s );
    124     }
    125 }
    12664
    12765/***
     
    310248        }
    311249
    312         if( easy ) {
     250        if( easy )
     251        {
    313252            long code;
    314             long fd;
    315253            struct tr_web_task * task;
    316             CURLcode ecode;
    317             CURLMcode mcode;
    318 
    319             ecode = curl_easy_getinfo( easy, CURLINFO_PRIVATE, (void*)&task );
    320             tr_assert( ecode == CURLE_OK, "curl_easy_getinfo() failed: %d (%s)", ecode, curl_easy_strerror( ecode ) );
    321 
    322             ecode = curl_easy_getinfo( easy, CURLINFO_RESPONSE_CODE, &code );
    323             tr_assert( ecode == CURLE_OK, "curl_easy_getinfo() failed: %d (%s)", ecode, curl_easy_strerror( ecode ) );
    324 
    325             ecode = curl_easy_getinfo( easy, CURLINFO_LASTSOCKET, &fd );
    326             tr_assert( ecode == CURLE_OK, "curl_easy_getinfo() failed: %d (%s)", ecode, curl_easy_strerror( ecode ) );
    327             if( fd != -1L )
    328                 purgeSockinfo( g, fd );
    329 
    330             mcode = curl_multi_remove_handle( g->multi, easy );
    331             tr_assert( mcode == CURLM_OK, "curl_multi_remove_handle() failed: %d (%s)", mcode, curl_multi_strerror( mcode ) );
    332 
     254            curl_easy_getinfo( easy, CURLINFO_PRIVATE, (void*)&task );
     255            curl_easy_getinfo( easy, CURLINFO_RESPONSE_CODE, &code );
     256            curl_multi_remove_handle( g->multi, easy );
    333257            curl_easy_cleanup( easy );
    334258            task_finish( task, code );
     
    343267stop_timer( tr_web* g )
    344268{
    345     if( evtimer_pending( &g->timer_event, NULL ) )
    346     {
    347         dbgmsg( "deleting the pending global timer" );
    348         evtimer_del( &g->timer_event );
    349     }
     269    dbgmsg( "deleting the pending global timer" );
     270    evtimer_del( &g->timer_event );
    350271}
    351272
     
    403324
    404325    if( !g->still_running ) {
    405         assert( tr_list_size( g->fds ) == 0 );
    406326        stop_timer( g );
    407327        if( g->closing ) {
     
    424344/* CURLMOPT_SOCKETFUNCTION */
    425345static int
    426 sock_cb( CURL            * e UNUSED,
     346sock_cb( CURL            * easy UNUSED,
    427347         curl_socket_t     fd,
    428348         int               action,
    429349         void            * vweb,
    430          void            * unused UNUSED)
    431 {
     350         void            * vevent )
     351{
     352    /*static int num_events = 0;*/
    432353    struct tr_web * web = vweb;
    433     dbgmsg( "sock_cb: action is %d, fd is %d", action, (int)fd );
     354    struct event * io_event = vevent;
     355    dbgmsg( "sock_cb: action is %d, fd is %d, io_event is %p", action, (int)fd, io_event );
    434356
    435357    if( action == CURL_POLL_REMOVE )
    436358    {
    437         purgeSockinfo( web, fd );
     359        if( io_event != NULL )
     360        {
     361            event_del( io_event );
     362            tr_free( io_event );
     363            curl_multi_assign( web->multi, fd, NULL ); /* does libcurl do this automatically? */
     364            /*fprintf( stderr, "-1 io_events to %d\n", --num_events );*/
     365        }
    438366    }
    439367    else
    440368    {
    441         struct tr_web_sockinfo * sockinfo = getSockinfo( web, fd, TRUE );
    442         const int kind = EV_PERSIST
    443                        | (( action & CURL_POLL_IN ) ? EV_READ : 0 )
    444                        | (( action & CURL_POLL_OUT ) ? EV_WRITE : 0 );
    445         dbgmsg( "setsock: fd is %d, curl action is %d, libevent action is %d", fd, action, kind );
    446         assert( tr_amInEventThread( web->session ) );
    447         assert( kind != EV_PERSIST );
    448 
    449         /* clear any old polling on this fd */
    450         clearSockinfoEvent( sockinfo );
    451 
    452         /* set the new polling on this fd */
    453         dbgmsg( "enabling (libevent %d, libcurl %d) polling on sockinfo %p, fd %d", action, kind, sockinfo, fd );
    454         event_set( &sockinfo->ev, fd, kind, event_cb, web );
    455         event_add( &sockinfo->ev, NULL );
    456         sockinfo->evset = TRUE;
    457     }
    458 
    459     return 0;
     369        const short events = EV_PERSIST
     370                           | (( action & CURL_POLL_IN ) ? EV_READ : 0 )
     371                           | (( action & CURL_POLL_OUT ) ? EV_WRITE : 0 );
     372
     373        if( io_event != NULL )
     374            event_del( io_event );
     375        else {
     376            io_event = tr_new0( struct event, 1 );
     377            curl_multi_assign( web->multi, fd, io_event );
     378            /*fprintf( stderr, "+1 io_events to %d\n", ++num_events );*/
     379        }
     380
     381        dbgmsg( "enabling (libevent %hd, libcurl %d) polling on io_event %p, fd %d", events, action, io_event, fd );
     382        event_set( io_event, fd, events, event_cb, web );
     383        event_add( io_event, NULL );
     384    }
     385
     386    return 0; /* libcurl doc sez: "The callback MUST return 0." */
    460387}
    461388
     
    539466
    540467    web = tr_new0( struct tr_web, 1 );
     468    web->session = session;
     469
     470    web->timer_msec = DEFAULT_TIMER_MSEC; /* overwritten by multi_timer_cb() */
     471    evtimer_set( &web->timer_event, libevent_timer_cb, web );
     472
    541473    web->multi = curl_multi_init( );
    542     web->session = session;
    543     web->timer_msec = DEFAULT_TIMER_MSEC; /* overwritten by multi_timer_cb() */
    544 
    545     evtimer_set( &web->timer_event, libevent_timer_cb, web );
    546474    curl_multi_setopt( web->multi, CURLMOPT_SOCKETDATA, web );
    547475    curl_multi_setopt( web->multi, CURLMOPT_SOCKETFUNCTION, sock_cb );
Note: See TracChangeset for help on using the changeset viewer.