Changeset 9749


Ignore:
Timestamp:
Dec 14, 2009, 5:11:33 AM (12 years ago)
Author:
charles
Message:

(trunk libT) keep simplifying web.c. also, fix an improbable FMR at shutdown

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/web.c

    r9742 r9749  
    1111 */
    1212
    13 #include <assert.h>
    14 #include <stdlib.h> /* bsearch */
    15 
    16 #define CURL_DISABLE_TYPECHECK /* otherwise -Wunreachable-code goes insane */
    1713#include <curl/curl.h>
    1814#include <event.h>
     
    3127};
    3228
    33 static void
    34 tr_multi_perform( tr_web * g, int fd );
     29static tr_bool tr_multi_perform( tr_web * g, int fd );
    3530
    3631#if 0
     
    5146{
    5247    tr_bool closing;
    53     int prev_running;
    54     int still_running;
     48    int taskCount;
    5549    long timer_msec;
    5650    CURLM * multi;
     
    8680}
    8781
    88 static int
    89 getCurlProxyType( tr_proxy_type t )
    90 {
    91     switch( t )
    92     {
    93         case TR_PROXY_SOCKS4: return CURLPROXY_SOCKS4;
    94         case TR_PROXY_SOCKS5: return CURLPROXY_SOCKS5;
    95         default:              return CURLPROXY_HTTP;
    96     }
    97 }
    98 
    9982static void
    10083sockoptfunction( void * vtask, curl_socket_t fd, curlsocktype purpose UNUSED )
     
    11699
    117100static int
     101getCurlProxyType( tr_proxy_type t )
     102{
     103    if( t == TR_PROXY_SOCKS4 ) return CURLPROXY_SOCKS4;
     104    if( t == TR_PROXY_SOCKS5 ) return CURLPROXY_SOCKS5;
     105    return CURLPROXY_HTTP;
     106}
     107
     108static int
    118109getTimeoutFromURL( const char * url )
    119110{
    120     if( strstr( url, "scrape" ) != NULL )
    121         return 20;
    122     if( strstr( url, "announce" ) != NULL )
    123         return 30;
     111    if( strstr( url, "scrape" ) != NULL ) return 20;
     112    if( strstr( url, "announce" ) != NULL ) return 30;
    124113    return 240;
    125114}
     
    161150        curl_easy_setopt( easy, CURLOPT_SOCKOPTFUNCTION, sockoptfunction );
    162151        curl_easy_setopt( easy, CURLOPT_SOCKOPTDATA, task );
     152        curl_easy_setopt( easy, CURLOPT_WRITEDATA, task );
     153        curl_easy_setopt( easy, CURLOPT_WRITEFUNCTION, writeFunc );
    163154        curl_easy_setopt( easy, CURLOPT_DNS_CACHE_TIMEOUT, 1800L );
    164155        curl_easy_setopt( easy, CURLOPT_FOLLOWLOCATION, 1L );
     
    173164        curl_easy_setopt( easy, CURLOPT_USERAGENT, user_agent );
    174165        curl_easy_setopt( easy, CURLOPT_VERBOSE, verbose );
    175         curl_easy_setopt( easy, CURLOPT_WRITEDATA, task );
    176         curl_easy_setopt( easy, CURLOPT_WRITEFUNCTION, writeFunc );
    177166        if( web->haveAddr )
    178             curl_easy_setopt( easy, CURLOPT_INTERFACE, tr_ntop_non_ts( &web->addr ) );
     167            curl_easy_setopt( easy, CURLOPT_INTERFACE,
     168                                            tr_ntop_non_ts( &web->addr ) );
    179169        if( task->range )
    180170            curl_easy_setopt( easy, CURLOPT_RANGE, task->range );
     
    183173
    184174        mcode = curl_multi_add_handle( web->multi, easy );
    185         if( mcode == CURLM_OK )
    186             ++web->still_running;
    187         else
    188             tr_err( "%s", curl_multi_strerror( mcode ) );
    189 
     175        ++web->taskCount;
    190176        /*tr_multi_perform( web, CURL_SOCKET_TIMEOUT );*/
    191177    }
     
    237223        }
    238224    }
    239 
    240     g->prev_running = g->still_running;
    241 }
    242 
    243 static void
    244 stop_timer( tr_web* g )
    245 {
    246     dbgmsg( "deleting the pending global timer" );
     225}
     226
     227static void
     228restart_timer( tr_web * g )
     229{
     230    dbgmsg( "adding a timeout for %.1f seconds from now", g->timer_msec/1000.0 );
    247231    evtimer_del( &g->timer_event );
    248 }
    249 
    250 static void
    251 restart_timer( tr_web * g )
    252 {
    253     assert( tr_amInEventThread( g->session ) );
    254     assert( g->session != NULL );
    255     assert( g->session->events != NULL );
    256 
    257     stop_timer( g );
    258     dbgmsg( "adding a timeout for %.1f seconds from now", g->timer_msec/1000.0 );
    259232    tr_timerAddMsec( &g->timer_event, g->timer_msec );
    260233}
     
    263236web_close( tr_web * g )
    264237{
    265     CURLMcode mcode;
    266 
    267     stop_timer( g );
    268 
    269     mcode = curl_multi_cleanup( g->multi );
    270     tr_assert( mcode == CURLM_OK, "curl_multi_cleanup() failed: %d (%s)", mcode, curl_multi_strerror( mcode ) );
    271     if( mcode != CURLM_OK )
    272         tr_err( "%s", curl_multi_strerror( mcode ) );
    273 
     238    curl_multi_cleanup( g->multi );
     239    evtimer_del( &g->timer_event );
    274240    tr_free( g );
    275241}
     
    278244   and no tasks remain.  callers must not reference their g pointer
    279245   after calling this function */
    280 static void
     246static tr_bool
    281247tr_multi_perform( tr_web * g, int fd )
    282248{
    283     int closed = FALSE;
     249    tr_bool closed = FALSE;
    284250    CURLMcode mcode;
    285251
    286     dbgmsg( "check_run_count: prev_running %d, still_running %d",
    287             g->prev_running, g->still_running );
     252    dbgmsg( "check_run_count: %d taskCount", g->taskCount );
    288253
    289254    /* invoke libcurl's processing */
    290255    do {
    291         mcode = curl_multi_socket_action( g->multi, fd, 0, &g->still_running );
     256        mcode = curl_multi_socket_action( g->multi, fd, 0, &g->taskCount );
    292257    } while( mcode == CURLM_CALL_MULTI_SOCKET );
    293258
    294259    remove_finished_tasks( g );
    295260
    296     if( !g->still_running ) {
    297         stop_timer( g );
    298         if( g->closing ) {
    299             web_close( g );
    300             closed = TRUE;
    301         }
     261    if( g->closing && !g->taskCount ) {
     262        web_close( g );
     263        closed = TRUE;
    302264    }
    303265
    304266    if( !closed )
    305267        restart_timer( g );
     268
     269    return closed;
    306270}
    307271
     
    328292            event_del( io_event );
    329293            tr_free( io_event );
    330             curl_multi_assign( web->multi, fd, NULL ); /* does libcurl do this automatically? */
     294            curl_multi_assign( web->multi, fd, NULL );
    331295            /*fprintf( stderr, "-1 io_events to %d\n", --num_events );*/
    332296        }
     
    371335{
    372336    tr_web * g = vg;
     337    tr_bool closed = FALSE;
    373338
    374339    if( timer_msec < 1 ) {
    375340        if( timer_msec == 0 ) /* call it immediately */
    376             libevent_timer_cb( 0, 0, g );
     341            closed = tr_multi_perform( g, CURL_SOCKET_TIMEOUT );
    377342        timer_msec = DEFAULT_TIMER_MSEC;
    378343    }
    379344
    380     g->timer_msec = timer_msec;
    381     restart_timer( g );
     345    if( !closed ) {
     346        g->timer_msec = timer_msec;
     347        restart_timer( g );
     348    }
    382349}
    383350
     
    395362    if( session->web )
    396363    {
    397         struct tr_web_task * task;
    398364        static unsigned long tag = 0;
    399 
    400         task = tr_new0( struct tr_web_task, 1 );
     365        struct tr_web_task * task = tr_new0( struct tr_web_task, 1 );
    401366        task->session = session;
    402367        task->url = tr_strdup( url );
     
    452417    tr_web * web = *web_in;
    453418    *web_in = NULL;
    454     if( web->still_running < 1 )
     419    if( web->taskCount < 1 )
    455420        web_close( web );
    456421    else
     
    463428*****/
    464429
    465 static struct http_msg {
     430static const struct http_msg {
    466431    long code;
    467432    const char * text;
     
    510475};
    511476
    512 static int
    513 compareResponseCodes( const void * va, const void * vb )
    514 {
    515     const long a = *(const long*) va;
    516     const struct http_msg * b = vb;
    517     return a - b->code;
    518 }
    519 
    520477const char *
    521478tr_webGetResponseStr( long code )
    522479{
    523     struct http_msg * msg = bsearch( &code,
    524                                      http_msg,
    525                                      sizeof( http_msg ) / sizeof( http_msg[0] ),
    526                                      sizeof( http_msg[0] ),
    527                                      compareResponseCodes );
    528     return msg ? msg->text : "Unknown Error";
    529 }
    530 
    531 /* escapes a string to be URI-legal as per RFC 2396.
    532    like curl_escape() but can optionally avoid escaping slashes. */
     480    int i;
     481    static const int n = sizeof( http_msg ) / sizeof( http_msg[0] );
     482    for( i=0; i<n; ++i )
     483        if( http_msg[i].code == code )
     484            return http_msg[i].text;
     485    return "Unknown Error";
     486}
     487
    533488void
    534 tr_http_escape( struct evbuffer  * out,
    535                 const char       * str,
    536                 int                len,
    537                 tr_bool            escape_slashes )
     489tr_http_escape( struct evbuffer  * out, const char * str, int len, tr_bool escape_slashes )
    538490{
    539491    int i;
     
    572524}
    573525
    574 char*
     526char *
    575527tr_http_unescape( const char * str, int len )
    576528{
Note: See TracChangeset for help on using the changeset viewer.