Changeset 2975


Ignore:
Timestamp:
Sep 5, 2007, 11:01:56 PM (15 years ago)
Author:
charles
Message:

(trunk) fix some of the crash-on-shutdown issues.

Location:
trunk/libtransmission
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/platform.c

    r2865 r2975  
    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    int ret;
     132#ifdef __BEOS__
     133    ret = find_thread(NULL) == t->thread;
     134#elif defined(WIN32)
     135    ret = GetCurrentThreadId() == t->thread_id;
     136#else
     137    ret = pthread_equal( t->thread, pthread_self( ) );
     138#endif
     139    return ret;
     140}
     141   
    127142void
    128143tr_threadJoin( tr_thread_t * t )
     
    349364    int start, end;
    350365#elif defined(WIN32)
    351     tr_list_t * events;
     366    tr_list * events;
    352367    tr_lock_t * lock;
    353368#else
     
    492507#elif defined(WIN32)
    493508
    494     tr_list_t * l;
     509    tr_list * l;
    495510    tr_lockLock( c->lock );
    496511    for( l=c->events; l!=NULL; l=l->next )
  • trunk/libtransmission/platform.h

    r2552 r2975  
    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 );
  • trunk/libtransmission/timer.c

    r2915 r2975  
    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 );
    79     else {
    80         timeout_add( node->event, &node->tv );
    81         unref( node, 1 );
     56    if( !node->doFree )
     57         node->doFree = !(node->func)(node->user_data);
     58
     59    if( node->doFree ) {
     60        if( node->free_func != NULL )
     61            (node->free_func)( node->user_data );
     62        tr_event_del( node->handle, node->event );
     63        tr_free( node );
    8264    }
    8365}
     
    10284    node->user_data = user_data;
    10385    node->free_func = free_func;
    104     node->refcount = 1;
     86    node->doFree = 0;
    10587    node->tv = timevalMsec ( timeout_milliseconds );
    10688    timeout_set( node->event, timerCB, node );
  • trunk/libtransmission/timer.h

    r2849 r2975  
    2626 * if user_data has resources that need to be freed.
    2727 */
    28 tr_timer_tag  tr_timerNew( struct tr_handle_s   * handle,
    29                            int                    timer_func( void * user_data ),
    30                            void                 * user_data,
    31                            void                   free_func( void * user_data ),
    32                            int                    timeout_milliseconds );
     28tr_timer_tag  tr_timerNew( struct tr_handle_s  * handle,
     29                           int                  timer_func( void * user_data ),
     30                           void               * user_data,
     31                           void                 free_func( void * user_data ),
     32                           int                  timeout_milliseconds );
    3333
    3434/**
  • trunk/libtransmission/trevent.c

    r2885 r2975  
    1515#include <stdlib.h>
    1616#include <string.h>
     17#include <stdio.h>
    1718
    1819#include <sys/queue.h> /* for evhttp */
     
    4950    tr_lock_t * lock;
    5051    tr_handle_t * h;
     52    tr_thread_t * thread;
    5153    struct event_base * base;
    5254    struct event pipeEvent;
     
    7173    enum evhttp_cmd_type type;
    7274    char * uri;
     75    char * buf;
     76    size_t buflen;
     77    struct bufferevent * bufev;
     78    short mode;
    7379
    7480#ifdef DEBUG
     
    8995        case 'd': /* event_del */
    9096            read( fd, &event, sizeof(struct event*) );
    91             tr_dbg( "read del event from pipe: event is %p", event );
    9297            event_del( event );
    9398            tr_free( event );
     
    97102            read( fd, &event, sizeof(struct event*) );
    98103            read( fd, &interval, sizeof(struct timeval) );
    99             tr_dbg( "read event from pipe: event.ev_arg is %p", event->ev_arg );
    100104            event_add( event, &interval );
    101105            break;
     
    106110            read( fd, &type, sizeof(enum evhttp_cmd_type) );
    107111            read( fd, &uri, sizeof(char*) );
    108             tr_dbg( "read http req from pipe: req.cb_arg is %p", req->cb_arg );
    109112            evhttp_make_request( evcon, req, type, uri );
    110113            tr_free( uri );
     114            break;
     115
     116        case 'm': /* set bufferevent mode */
     117            read( fd, &bufev, sizeof(struct evhttp_request*) );
     118            mode = 0;
     119            read( fd, &mode, sizeof(short) );
     120            bufferevent_enable( bufev, mode );
     121            mode = 0;
     122            read( fd, &mode, sizeof(short) );
     123            bufferevent_disable( bufev, mode );
     124fprintf( stderr, "after enable/disable, the mode is %hd\n", bufev->enabled );
     125            break;
     126
     127        case 'w': /* bufferevent_write */
     128            read( fd, &bufev, sizeof(struct bufferevent*) );
     129            read( fd, &buf, sizeof(char*) );
     130            read( fd, &buflen, sizeof(size_t) );
     131            bufferevent_write( bufev, buf, buflen );
     132            tr_free( buf );
    111133            break;
    112134
     
    166188    eh->h = handle;
    167189    handle->events = eh;
    168     tr_threadNew( libeventThreadFunc, eh, "libeventThreadFunc" );
     190    eh->thread = tr_threadNew( libeventThreadFunc, eh, "libeventThreadFunc" );
    169191}
    170192
     
    182204              struct timeval * interval )
    183205{
    184     const char ch = 'e';
    185     int fd = handle->events->fds[1];
    186     tr_lock_t * lock = handle->events->lock;
    187 
    188     tr_lockLock( lock );
    189     tr_dbg( "writing event to pipe: event.ev_arg is %p", event->ev_arg );
    190 #ifdef DEBUG
    191     fprintf( stderr, "reads: [%d] writes: [%d]\n", reads, ++writes );
    192 #endif
    193     write( fd, &ch, 1 );
    194     write( fd, &event, sizeof(struct event*) );
    195     write( fd, interval, sizeof(struct timeval) );
    196     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    }
    197223}
    198224
     
    201227              struct event   * event )
    202228{
    203     const char ch = 'd';
    204     int fd = handle->events->fds[1];
    205     tr_lock_t * lock = handle->events->lock;
    206 
    207     tr_lockLock( lock );
    208     tr_dbg( "writing event to pipe: del event %p", event );
    209 #ifdef DEBUG
    210     fprintf( stderr, "reads: [%d] writes: [%d]\n", reads, ++writes );
    211 #endif
    212     write( fd, &ch, 1 );
    213     write( fd, &event, sizeof(struct event*) );
    214     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    }
    215246}
    216247
     
    222253                        char                      * uri)
    223254{
    224     const char ch = 'h';
    225     int fd = handle->events->fds[1];
    226     tr_lock_t * lock = handle->events->lock;
    227 
    228     tr_lockLock( lock );
    229     tr_dbg( "writing HTTP req to pipe: req.cb_arg is %p", req->cb_arg );
    230 #ifdef DEBUG
    231     fprintf( stderr, "reads: [%d] writes: [%d]\n", reads, ++writes );
    232 #endif
    233     write( fd, &ch, 1 );
    234     write( fd, &evcon, sizeof(struct evhttp_connection*) );
    235     write( fd, &req, sizeof(struct evhttp_request*) );
    236     write( fd, &type, sizeof(enum evhttp_cmd_type) );
    237     write( fd, &uri, sizeof(char*) );
    238     tr_lockUnlock( lock );
    239 }
     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    }
     275}
     276
     277void
     278tr_bufferevent_write( tr_handle_t           * handle,
     279                      struct bufferevent    * bufev,
     280                      const void            * buf,
     281                      size_t                  buflen )
     282{
     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    }
     302}
     303
     304void
     305tr_setBufferEventMode( struct tr_handle_s   * handle,
     306                       struct bufferevent * bufev,
     307                       short                mode_enable,
     308                       short                mode_disable )
     309{
     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}
  • trunk/libtransmission/trevent.h

    r2876 r2975  
    1212
    1313#ifndef TR_EVENT_H
     14
     15#include <stddef.h> /* for size_t */
    1416
    1517/**
     
    2729struct evhttp_request;
    2830struct evhttp_connection;
     31struct bufferevent;
    2932
    3033void  tr_event_add( struct tr_handle_s  * tr_handle,
    31                     struct event        * event,
    32                     struct timeval      * interval );
     34                    struct event      * event,
     35                    struct timeval    * interval );
    3336
    3437void  tr_event_del( struct tr_handle_s  * tr_handle,
    35                     struct event        * event );
     38                    struct event      * event );
    3639
    37 void tr_evhttp_make_request (struct tr_handle_s        * tr_handle,
     40void tr_evhttp_make_request (struct tr_handle_s          * tr_handle,
    3841                             struct evhttp_connection  * evcon,
    3942                             struct evhttp_request     * req,
     
    4144                             char                      * uri);
    4245
     46void tr_bufferevent_write( struct tr_handle_s    * tr_handle,
     47                           struct bufferevent  * bufferEvent,
     48                           const void          * buf,
     49                           size_t                buflen );
     50
     51void tr_setBufferEventMode( struct tr_handle_s   * tr_handle,
     52                            struct bufferevent * bufferEvent,
     53                            short                mode_enable,
     54                            short                mode_disable );
     55
    4356#endif
Note: See TracChangeset for help on using the changeset viewer.