Changeset 2977


Ignore:
Timestamp:
Sep 6, 2007, 12:23:00 AM (14 years ago)
Author:
charles
Message:
  • fix some threading issues.
  • avoid the trevent read/write pipe when possible.
  • better cleanup on shutdown.
Location:
branches/encryption/libtransmission
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/encryption/libtransmission/platform.c

    r2942 r2977  
    6767#elif defined(WIN32)
    6868    HANDLE           thread;
     69    unsigned int     thread_id;
    6970#else
    7071    pthread_t        thread;
     
    117118    resume_thread( t->thread );
    118119#elif defined(WIN32)
    119     t->thread = (HANDLE) _beginthreadex( NULL, 0, &ThreadFunc, t, 0, NULL );
     120    t->thread = (HANDLE) _beginthreadex( NULL, 0, &ThreadFunc, t, 0, &t->thread_id );
    120121#else
    121122    pthread_create( &t->thread, NULL, (void * (*) (void *)) ThreadFunc, t );
     
    125126}
    126127
     128int
     129tr_amInThread ( const tr_thread_t * t )
     130{
     131#ifdef __BEOS__
     132    return find_thread(NULL) == t->thread;
     133#elif defined(WIN32)
     134    return GetCurrentThreadId() == t->thread_id;
     135#else
     136    return pthread_equal( t->thread, pthread_self( ) );
     137#endif
     138}
     139   
    127140void
    128141tr_threadJoin( tr_thread_t * t )
  • branches/encryption/libtransmission/platform.h

    r2552 r2977  
    3535tr_thread_t*  tr_threadNew  ( void (*func)(void *), void * arg, const char * name );
    3636void          tr_threadJoin ( tr_thread_t * );
     37int           tr_amInThread ( const tr_thread_t * );
    3738
    3839tr_lock_t * tr_lockNew        ( void );
  • branches/encryption/libtransmission/timer.c

    r2915 r2977  
    3636    tr_data_free_func * free_func;
    3737    struct timeval tv;
    38     int refcount;
     38    uint8_t doFree;
    3939};
    40 
    41 static void
    42 unref( struct timer_node * node, int count )
    43 {
    44     assert( node != NULL );
    45     assert( node->refcount > 0 );
    46 
    47     node->refcount -= count;
    48     if( node->refcount > 0 )
    49         return;
    50 
    51     if( node->free_func != NULL )
    52         (node->free_func)( node->user_data );
    53     tr_event_del( node->handle, node->event );
    54     tr_free( node );
    55 }
    5640
    5741void
    5842tr_timerFree( struct timer_node ** node )
    5943{
    60     assert( node != NULL );
    61 
    6244    if( *node )
    6345    {
    64         unref( *node, 1 );
     46        (*node)->doFree = 1;
    6547        *node = NULL;
    6648    }
     
    7153{
    7254    struct timer_node * node = (struct timer_node *) arg;
    73     int val;
    7455
    75     ++node->refcount;
    76     val = (node->func)(node->user_data);
    77     if( !val )
    78         unref( node, 2 );
     56    if( !node->doFree )
     57         node->doFree = !(node->func)(node->user_data);
     58
     59    if( !node->doFree )
     60        tr_event_add( node->handle, node->event, &node->tv );
    7961    else {
    80         timeout_add( node->event, &node->tv );
    81         unref( node, 1 );
     62        if( node->free_func != NULL )
     63            (node->free_func)( node->user_data );
     64        tr_event_del( node->handle, node->event );
     65        tr_free( node );
    8266    }
    8367}
     
    10286    node->user_data = user_data;
    10387    node->free_func = free_func;
    104     node->refcount = 1;
     88    node->doFree = 0;
    10589    node->tv = timevalMsec ( timeout_milliseconds );
    10690    timeout_set( node->event, timerCB, node );
  • branches/encryption/libtransmission/trevent.c

    r2971 r2977  
    5050    tr_lock_t * lock;
    5151    tr_handle_t * h;
     52    tr_thread_t * thread;
    5253    struct event_base * base;
    5354    struct event pipeEvent;
     
    187188    eh->h = handle;
    188189    handle->events = eh;
    189     tr_threadNew( libeventThreadFunc, eh, "libeventThreadFunc" );
     190    eh->thread = tr_threadNew( libeventThreadFunc, eh, "libeventThreadFunc" );
    190191}
    191192
     
    203204              struct timeval * interval )
    204205{
    205     const char ch = 'e';
    206     int fd = handle->events->fds[1];
    207     tr_lock_t * lock = handle->events->lock;
    208 
    209     tr_lockLock( lock );
    210     tr_dbg( "writing event to pipe: event.ev_arg is %p", event->ev_arg );
    211 #ifdef DEBUG
    212     fprintf( stderr, "reads: [%d] writes: [%d]\n", reads, ++writes );
    213 #endif
    214     write( fd, &ch, 1 );
    215     write( fd, &event, sizeof(struct event*) );
    216     write( fd, interval, sizeof(struct timeval) );
    217     tr_lockUnlock( lock );
     206    if( tr_amInThread( handle->events->thread ) )
     207    {
     208        event_add( event, interval );
     209    }
     210    else
     211    {
     212        const char ch = 'e';
     213        int fd = handle->events->fds[1];
     214        tr_lock_t * lock = handle->events->lock;
     215
     216        tr_lockLock( lock );
     217        tr_dbg( "writing event to pipe: event.ev_arg is %p", event->ev_arg );
     218        write( fd, &ch, 1 );
     219        write( fd, &event, sizeof(struct event*) );
     220        write( fd, interval, sizeof(struct timeval) );
     221        tr_lockUnlock( lock );
     222    }
    218223}
    219224
     
    222227              struct event   * event )
    223228{
    224     const char ch = 'd';
    225     int fd = handle->events->fds[1];
    226     tr_lock_t * lock = handle->events->lock;
    227 
    228     tr_lockLock( lock );
    229     tr_dbg( "writing event to pipe: del event %p", event );
    230 #ifdef DEBUG
    231     fprintf( stderr, "reads: [%d] writes: [%d]\n", reads, ++writes );
    232 #endif
    233     write( fd, &ch, 1 );
    234     write( fd, &event, sizeof(struct event*) );
    235     tr_lockUnlock( lock );
     229    if( tr_amInThread( handle->events->thread ) )
     230    {
     231        event_del( event );
     232        tr_free( event );
     233    }
     234    else
     235    {
     236        const char ch = 'd';
     237        int fd = handle->events->fds[1];
     238        tr_lock_t * lock = handle->events->lock;
     239
     240        tr_lockLock( lock );
     241        tr_dbg( "writing event to pipe: del event %p", event );
     242        write( fd, &ch, 1 );
     243        write( fd, &event, sizeof(struct event*) );
     244        tr_lockUnlock( lock );
     245    }
    236246}
    237247
     
    243253                        char                      * uri)
    244254{
    245     const char ch = 'h';
    246     int fd = handle->events->fds[1];
    247     tr_lock_t * lock = handle->events->lock;
    248 
    249     tr_lockLock( lock );
    250     tr_dbg( "writing HTTP req to pipe: req.cb_arg is %p", req->cb_arg );
    251 #ifdef DEBUG
    252     fprintf( stderr, "reads: [%d] writes: [%d]\n", reads, ++writes );
    253 #endif
    254     write( fd, &ch, 1 );
    255     write( fd, &evcon, sizeof(struct evhttp_connection*) );
    256     write( fd, &req, sizeof(struct evhttp_request*) );
    257     write( fd, &type, sizeof(enum evhttp_cmd_type) );
    258     write( fd, &uri, sizeof(char*) );
    259     tr_lockUnlock( lock );
     255    if( tr_amInThread( handle->events->thread ) )
     256    {
     257        evhttp_make_request( evcon, req, type, uri );
     258        tr_free( uri );
     259    }
     260    else
     261    {
     262        const char ch = 'h';
     263        int fd = handle->events->fds[1];
     264        tr_lock_t * lock = handle->events->lock;
     265
     266        tr_lockLock( lock );
     267        tr_dbg( "writing HTTP req to pipe: req.cb_arg is %p", req->cb_arg );
     268        write( fd, &ch, 1 );
     269        write( fd, &evcon, sizeof(struct evhttp_connection*) );
     270        write( fd, &req, sizeof(struct evhttp_request*) );
     271        write( fd, &type, sizeof(enum evhttp_cmd_type) );
     272        write( fd, &uri, sizeof(char*) );
     273        tr_lockUnlock( lock );
     274    }
    260275}
    261276
     
    266281                      size_t                  buflen )
    267282{
    268     const char ch = 'w';
    269     int fd = handle->events->fds[1];
    270     tr_lock_t * lock = handle->events->lock;
    271     char * local = tr_strndup( buf, buflen );
    272 
    273     tr_lockLock( lock );
    274     tr_dbg( "writing bufferevent_write pipe" );
    275     write( fd, &ch, 1 );
    276     write( fd, &bufev, sizeof(struct bufferevent*) );
    277     write( fd, &local, sizeof(char*) );
    278     write( fd, &buflen, sizeof(size_t) );
    279     tr_lockUnlock( lock );
     283    if( tr_amInThread( handle->events->thread ) )
     284    {
     285        bufferevent_write( bufev, (void*)buf, buflen );
     286    }
     287    else
     288    {
     289        const char ch = 'w';
     290        int fd = handle->events->fds[1];
     291        tr_lock_t * lock = handle->events->lock;
     292        char * local = tr_strndup( buf, buflen );
     293
     294        tr_lockLock( lock );
     295        tr_dbg( "writing bufferevent_write pipe" );
     296        write( fd, &ch, 1 );
     297        write( fd, &bufev, sizeof(struct bufferevent*) );
     298        write( fd, &local, sizeof(char*) );
     299        write( fd, &buflen, sizeof(size_t) );
     300        tr_lockUnlock( lock );
     301    }
    280302}
    281303
     
    286308                       short                mode_disable )
    287309{
    288     const char ch = 'm';
    289     int fd = handle->events->fds[1];
    290     tr_lock_t * lock = handle->events->lock;
    291 
    292     tr_lockLock( lock );
    293     write( fd, &ch, 1 );
    294     write( fd, &bufev, sizeof(struct bufferevent*) );
    295     write( fd, &mode_enable, sizeof(short) );
    296     write( fd, &mode_disable, sizeof(short) );
    297     tr_lockUnlock( lock );
    298 }
     310    if( tr_amInThread( handle->events->thread ) )
     311    {
     312        bufferevent_enable( bufev, mode_enable );
     313        bufferevent_disable( bufev, mode_disable );
     314    }
     315    else
     316    {
     317        const char ch = 'm';
     318        int fd = handle->events->fds[1];
     319        tr_lock_t * lock = handle->events->lock;
     320
     321        tr_lockLock( lock );
     322        write( fd, &ch, 1 );
     323        write( fd, &bufev, sizeof(struct bufferevent*) );
     324        write( fd, &mode_enable, sizeof(short) );
     325        write( fd, &mode_disable, sizeof(short) );
     326        tr_lockUnlock( lock );
     327    }
     328}
Note: See TracChangeset for help on using the changeset viewer.