Changeset 7832 for trunk/libtransmission/web.c
- Timestamp:
- Feb 5, 2009, 10:00:21 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/web.c
r7831 r7832 50 50 #endif 51 51 52 struct tr_web_sockinfo 53 { 54 int fd; 55 tr_bool evset; 56 struct event ev; 57 }; 58 52 59 struct tr_web 53 60 { … … 58 65 CURLM * multi; 59 66 tr_session * session; 60 #if 061 tr_list * easy_queue;62 #endif63 67 struct event timer_event; 68 tr_list * fds; 64 69 }; 70 71 /*** 72 **** 73 ***/ 74 75 static struct tr_web_sockinfo * 76 getSockinfo( tr_web * web, int fd, tr_bool createIfMissing ) 77 { 78 tr_list * l = web->fds; 79 80 for( l=web->fds; l!=NULL; l=l->next ) { 81 struct tr_web_sockinfo * s = l->data; 82 if( s->fd == fd ) { 83 dbgmsg( "looked up sockinfo %p for fd %d", s, fd ); 84 return s; 85 } 86 } 87 88 if( createIfMissing ) { 89 struct tr_web_sockinfo * s = tr_new0( struct tr_web_sockinfo, 1 ); 90 s->fd = fd; 91 tr_list_prepend( &web->fds, s ); 92 dbgmsg( "created sockinfo %p for fd %d... we now have %d sockinfos", s, fd, tr_list_size(web->fds) ); 93 return s; 94 } 95 96 return NULL; 97 } 98 99 static void 100 clearSockinfoEvent( struct tr_web_sockinfo * s ) 101 { 102 if( s && s->evset ) 103 { 104 dbgmsg( "clearing libevent polling for sockinfo %p, fd %d", s, s->fd ); 105 event_del( &s->ev ); 106 s->evset = FALSE; 107 } 108 } 109 110 static void 111 purgeSockinfo( tr_web * web, int fd ) 112 { 113 struct tr_web_sockinfo * s = getSockinfo( web, fd, FALSE ); 114 115 if( s != NULL ) 116 { 117 tr_list_remove_data( &web->fds, s ); 118 clearSockinfoEvent( s ); 119 dbgmsg( "freeing sockinfo %p, fd %d", s, s->fd ); 120 tr_free( s ); 121 } 122 } 65 123 66 124 /*** … … 149 207 curl_easy_setopt( easy, CURLOPT_ENCODING, "" ); 150 208 151 #if 0152 if( web->still_running >= MAX_CONCURRENT_TASKS )153 {154 tr_list_append( &web->easy_queue, easy );155 dbgmsg( " >> enqueueing a task ... size is now %d",156 tr_list_size( web->easy_queue ) );157 }158 else159 #endif160 209 { 161 210 const CURLMcode mcode = curl_multi_add_handle( web->multi, easy ); … … 172 221 **** 173 222 ***/ 174 175 struct tr_web_sockinfo176 {177 struct event ev;178 int evset;179 };180 223 181 224 static void … … 264 307 } 265 308 266 #if 0267 static void268 add_tasks_from_queue( tr_web * g )269 {270 while( ( g->still_running < MAX_CONCURRENT_TASKS )271 && ( tr_list_size( g->easy_queue ) > 0 ) )272 {273 CURL * easy = tr_list_pop_front( &g->easy_queue );274 if( easy )275 {276 const CURLMcode rc = curl_multi_add_handle( g->multi, easy );277 if( rc != CURLM_OK )278 tr_err( "%s", curl_multi_strerror( rc ) );279 else {280 dbgmsg( "pumped the task queue, %d remain",281 tr_list_size( g->easy_queue ) );282 ++g->still_running;283 }284 }285 }286 }287 #endif288 289 309 static void 290 310 web_close( tr_web * g ) … … 319 339 dbgmsg( "event_cb(): fd %d, still_running is %d", fd, g->still_running ); 320 340 } while( mcode == CURLM_CALL_MULTI_PERFORM ); 321 tr_assert( mcode == CURLM_OK, "curl_multi_socket_action() failed on fd %d: %d (%s)", fd, mcode, curl_multi_strerror( mcode ) ); 322 if( mcode != CURLM_OK ) 323 tr_err( "%s", curl_multi_strerror( mcode ) ); 341 if( ( mcode == CURLM_BAD_SOCKET ) && ( fd != CURL_SOCKET_TIMEOUT ) ) 342 purgeSockinfo( g, fd ); 343 else { 344 tr_assert( mcode == CURLM_OK, "curl_multi_socket_action() failed on fd %d: %d (%s)", fd, mcode, curl_multi_strerror( mcode ) ); 345 if( mcode != CURLM_OK ) 346 tr_err( "%s", curl_multi_strerror( mcode ) ); 347 } 324 348 325 349 remove_finished_tasks( g ); 326 350 327 #if 0328 add_tasks_from_queue( g );329 #endif330 331 351 if( !g->still_running ) { 352 assert( tr_list_size( g->fds ) == 0 ); 332 353 stop_timer( g ); 333 354 if( g->closing ) { … … 356 377 } 357 378 358 static void359 remsock( struct tr_web_sockinfo * f )360 {361 if( f ) {362 dbgmsg( "deleting sockinfo %p", f );363 if( f->evset )364 event_del( &f->ev );365 tr_free( f );366 }367 }368 369 static void370 setsock( curl_socket_t sockfd,371 int action,372 struct tr_web * g,373 struct tr_web_sockinfo * f )374 {375 const int kind = EV_PERSIST376 | (( action & CURL_POLL_IN ) ? EV_READ : 0 )377 | (( action & CURL_POLL_OUT ) ? EV_WRITE : 0 );378 379 assert( tr_amInEventThread( g->session ) );380 assert( g->session != NULL );381 assert( g->session->events != NULL );382 383 dbgmsg( "setsock: fd is %d, curl action is %d, libevent action is %d",384 sockfd, action, kind );385 if( f->evset )386 event_del( &f->ev );387 event_set( &f->ev, sockfd, kind, event_cb, g );388 f->evset = 1;389 event_add( &f->ev, NULL );390 }391 392 static void393 addsock( curl_socket_t sockfd,394 int action,395 struct tr_web * g )396 {397 CURLMcode mcode;398 struct tr_web_sockinfo * f;399 400 f = tr_new0( struct tr_web_sockinfo, 1 );401 dbgmsg( "creating a sockinfo %p for fd %d", f, sockfd );402 setsock( sockfd, action, g, f );403 404 mcode = curl_multi_assign( g->multi, sockfd, f );405 tr_assert( mcode == CURLM_OK, "curl_multi_assign() failed: %d (%s)", mcode, curl_multi_strerror( mcode ) );406 if( mcode != CURLM_OK )407 tr_err( "%s", curl_multi_strerror( mcode ) );408 }409 410 379 /* CURLMOPT_SOCKETFUNCTION */ 411 380 static int 412 381 sock_cb( CURL * e UNUSED, 413 curl_socket_t s, 414 int what, 415 void * vg, 416 void * vf) 417 { 418 struct tr_web * g = vg; 419 struct tr_web_sockinfo * f = vf; 420 dbgmsg( "sock_cb: what is %d, sockinfo is %p", what, f ); 421 422 if( what == CURL_POLL_REMOVE ) 423 remsock( f ); 424 else if( !f ) 425 addsock( s, what, g ); 382 curl_socket_t fd, 383 int action, 384 void * vweb, 385 void * unused UNUSED) 386 { 387 struct tr_web * web = vweb; 388 dbgmsg( "sock_cb: action is %d, fd is %d", action, (int)fd ); 389 390 if( action == CURL_POLL_REMOVE ) 391 { 392 purgeSockinfo( web, fd ); 393 } 426 394 else 427 setsock( s, what, g, f ); 395 { 396 struct tr_web_sockinfo * sockinfo = getSockinfo( web, fd, TRUE ); 397 const int kind = EV_PERSIST 398 | (( action & CURL_POLL_IN ) ? EV_READ : 0 ) 399 | (( action & CURL_POLL_OUT ) ? EV_WRITE : 0 ); 400 dbgmsg( "setsock: fd is %d, curl action is %d, libevent action is %d", fd, action, kind ); 401 assert( tr_amInEventThread( web->session ) ); 402 assert( kind != EV_PERSIST ); 403 404 /* clear any old polling on this fd */ 405 clearSockinfoEvent( sockinfo ); 406 407 /* set the new polling on this fd */ 408 dbgmsg( "enabling (libevent %d, libcurl %d) polling on sockinfo %p, fd %d", action, kind, sockinfo, fd ); 409 event_set( &sockinfo->ev, fd, kind, event_cb, web ); 410 event_add( &sockinfo->ev, NULL ); 411 sockinfo->evset = TRUE; 412 } 428 413 429 414 return 0;
Note: See TracChangeset
for help on using the changeset viewer.