Changeset 3254


Ignore:
Timestamp:
Oct 1, 2007, 3:17:15 PM (15 years ago)
Author:
charles
Message:

simplify libT locks now that it's (more-or-less) single-threaded. fix deadlocks. make tr_locks nestable.

Location:
trunk/libtransmission
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/internal.h

    r3225 r3254  
    140140    run_status_t               runStatusToSave;
    141141    cp_status_t                cpStatus;
    142     struct tr_lock           * lock;
    143142
    144143    struct tr_tracker        * tracker;
     
    189188    struct tr_shared         * shared;
    190189
     190    struct tr_lock           * lock;
     191
    191192    tr_handle_status           stats[2];
    192193    int                        statCur;
     
    198199};
    199200
    200 #endif
     201void tr_globalLock       ( struct tr_handle * );
     202void tr_globalUnlock     ( struct tr_handle * );
     203int  tr_globalIsLocked   ( const struct tr_handle * );
     204
     205
     206#endif
  • trunk/libtransmission/makemeta.c

    r3111 r3254  
    416416    static tr_lock * lock = NULL;
    417417
    418     tr_sharedLock( h->shared );
     418    tr_globalLock( h );
    419419    if( !lock )
    420420         lock = tr_lockNew( );
    421     tr_sharedUnlock( h->shared );
     421    tr_globalUnlock( h );
    422422
    423423    return lock;
  • trunk/libtransmission/peer-mgr.c

    r3253 r3254  
    3030#include "ptrarray.h"
    3131#include "ratecontrol.h"
     32#include "shared.h"
    3233#include "trevent.h"
    3334#include "utils.h"
    34 
    35 #include "pthread.h"
    3635
    3736enum
     
    107106    int connectionCount;
    108107    tr_ptrArray * handshakes; /* in-process */
    109     tr_lock * lock;
    110     pthread_t lockThread;
    111108};
    112109
     
    118115managerLock( struct tr_peerMgr * manager )
    119116{
    120     assert( manager->lockThread != pthread_self() );
    121     tr_lockLock( manager->lock );
    122     manager->lockThread = pthread_self();
     117    tr_globalLock( manager->handle );
    123118}
    124119static void
    125120managerUnlock( struct tr_peerMgr * manager )
    126121{
    127     assert( manager->lockThread == pthread_self() );
    128     manager->lockThread = 0;
    129     tr_lockUnlock( manager->lock );
     122    tr_globalUnlock( manager->handle );
    130123}
    131124static void
     
    142135torrentIsLocked( const Torrent * t )
    143136{
    144     return ( t != NULL )
    145         && ( t->manager != NULL )
    146         && ( t->manager->lockThread != 0 )
    147         && ( t->manager->lockThread == pthread_self( ) );
     137    return ( t != NULL )
     138        && ( tr_globalIsLocked( t->manager->handle ) );
    148139}
    149140
     
    436427    m->torrents = tr_ptrArrayNew( );
    437428    m->handshakes = tr_ptrArrayNew( );
    438     m->lock = tr_lockNew( );
    439429    return m;
    440430}
     
    449439
    450440    managerUnlock( manager );
    451     tr_lockFree( manager->lock );
    452441    tr_free( manager );
    453442}
     
    483472    uint32_t peerCount;
    484473    uint32_t fastAllowed;
    485     uint32_t random;
     474    uint8_t random;
    486475};
    487476
     
    505494
    506495    /* otherwise go with our random seed */
    507     return tr_compareUint32( a->random, b->random );
     496    return tr_compareUint8( a->random, b->random );
    508497}
    509498
     
    557546            setme->peerCount = 0;
    558547            setme->fastAllowed = 0;
    559             setme->random = tr_rand( UINT32_MAX );
     548            setme->random = tr_rand( UINT8_MAX );
    560549            /* FIXME */
    561550//            setme->fastAllowed = tr_bitfieldHas( t->tor->allowedList, i);
     
    820809    Torrent * t = (Torrent *) vt;
    821810    const tr_peermsgs_event * e = (const tr_peermsgs_event *) vevent;
    822     const int needLock = !torrentIsLocked( t );
    823 
    824     if( needLock )
    825         torrentLock( t );
     811
     812    torrentLock( t );
    826813
    827814    switch( e->eventType )
     
    862849    }
    863850
    864     if( needLock )
    865         torrentUnlock( t );
     851    torrentUnlock( t );
    866852}
    867853
     
    965951    tr_handshake * handshake;
    966952
    967     assert( manager->lockThread!=0 );
    968953    assert( io != NULL );
    969954
     
    10921077{
    10931078    const Torrent * t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
    1094     const int isLocked = torrentIsLocked( t );
    10951079    int i, peerCount;
    10961080    const tr_peer ** peers;
     
    10981082    tr_pex * walk;
    10991083
    1100     if( !isLocked )
    1101         torrentLock( (Torrent*)t );
     1084    torrentLock( (Torrent*)t );
    11021085
    11031086    peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
     
    11211104    *setme_pex = pex;
    11221105
    1123     if( !isLocked )
    1124         torrentUnlock( (Torrent*)t );
     1106    torrentUnlock( (Torrent*)t );
    11251107
    11261108    return peerCount;
  • trunk/libtransmission/platform.c

    r3217 r3254  
    5757***/
    5858
     59#ifdef __BEOS__
     60typedef thread_id tr_thread_id;
     61#elif defined(WIN32)
     62typedef DWORD tr_thread_id;
     63#else
     64typedef pthread_t tr_thread_id;
     65#endif
     66
     67static tr_thread_id
     68tr_getCurrentThread( void )
     69{
     70#ifdef __BEOS__
     71    return find_thread( NULL );
     72#elif defined(WIN32)
     73    return GetCurrentThreadId();
     74#else
     75    return pthread_self( );
     76#endif
     77}
     78
     79static int
     80tr_areThreadsEqual( tr_thread_id a, tr_thread_id b )
     81{
     82#ifdef __BEOS__
     83    return a == b;
     84#elif defined(WIN32)
     85    return a == b;
     86#else
     87    return pthread_equal( a, b );
     88#endif
     89}
     90
    5991struct tr_thread
    6092{
     
    73105
    74106};
     107
     108int
     109tr_amInThread ( const tr_thread * t )
     110{
     111    return tr_areThreadsEqual( tr_getCurrentThread(), t->thread );
     112}
    75113
    76114#ifdef WIN32
     
    123161    return t;
    124162}
    125 
    126 int
    127 tr_amInThread ( const tr_thread * t )
    128 {
    129 #ifdef __BEOS__
    130     return find_thread(NULL) == t->thread;
    131 #elif defined(WIN32)
    132     return GetCurrentThreadId() == t->thread_id;
    133 #else
    134     return pthread_equal( t->thread, pthread_self( ) );
    135 #endif
    136 }
    137163   
    138164void
     
    164190struct tr_lock
    165191{
     192    uint32_t depth;
    166193#ifdef __BEOS__
    167194    sem_id lock;
     195    thread_id lockThread;
    168196#elif defined(WIN32)
    169197    CRITICAL_SECTION lock;
     198    DWORD lockThread;
    170199#else
    171200    pthread_mutex_t lock;
     201    pthread_t lockThread;
    172202#endif
    173203};
     
    217247tr_lockLock( tr_lock * l )
    218248{
    219 #ifdef __BEOS__
    220     acquire_sem( l->lock );
    221 #elif defined(WIN32)
    222     EnterCriticalSection( &l->lock );
    223 #else
    224     pthread_mutex_lock( &l->lock );
    225 #endif
     249    tr_thread_id currentThread = tr_getCurrentThread( );
     250    if( l->lockThread == currentThread )
     251    {
     252        ++l->depth;
     253    }
     254    else
     255    {
     256#ifdef __BEOS__
     257        acquire_sem( l->lock );
     258#elif defined(WIN32)
     259        EnterCriticalSection( &l->lock );
     260#else
     261        pthread_mutex_lock( &l->lock );
     262#endif
     263        l->lockThread = tr_getCurrentThread( );
     264        l->depth = 1;
     265    }
     266}
     267
     268int
     269tr_lockHave( const tr_lock * l )
     270{
     271    return ( l->depth > 0 )
     272        && ( l->lockThread == tr_getCurrentThread() );
    226273}
    227274
     
    229276tr_lockUnlock( tr_lock * l )
    230277{
    231 #ifdef __BEOS__
    232     release_sem( l->lock );
    233 #elif defined(WIN32)
    234     LeaveCriticalSection( &l->lock );
    235 #else
    236     pthread_mutex_unlock( &l->lock );
    237 #endif
     278    assert( tr_lockHave( l ) );
     279
     280    if( !--l->depth )
     281    {
     282        l->lockThread = 0;
     283#ifdef __BEOS__
     284        release_sem( l->lock );
     285#elif defined(WIN32)
     286        LeaveCriticalSection( &l->lock );
     287#else
     288        pthread_mutex_unlock( &l->lock );
     289#endif
     290    }
    238291}
    239292
  • trunk/libtransmission/platform.h

    r3107 r3254  
    4242void         tr_lockLock       ( tr_lock * );
    4343void         tr_lockUnlock     ( tr_lock * );
     44int          tr_lockHave       ( const tr_lock * );
    4445
    4546tr_cond *    tr_condNew       ( void );
  • trunk/libtransmission/shared.c

    r3171 r3254  
    4545{
    4646    tr_handle    * h;
    47     tr_lock      * lock;
    4847    tr_timer     * pulseTimer;
    4948
     
    7675
    7776    s->h          = h;
    78     s->lock       = tr_lockNew( );
    7977    s->publicPort = -1;
    8078    s->bindPort   = -1;
     
    9795
    9896    tr_netClose( s->bindSocket );
    99     tr_lockFree( s->lock );
    10097    tr_natpmpClose( s->natpmp );
    10198    tr_upnpClose( s->upnp );
    10299    free( s );
    103 }
    104 
    105 /**
    106 ***
    107 **/
    108 
    109 void tr_sharedLock( tr_shared * s )
    110 {
    111     tr_lockLock( s->lock );
    112 }
    113 void tr_sharedUnlock( tr_shared * s )
    114 {
    115     tr_lockUnlock( s->lock );
    116100}
    117101
     
    129113#endif
    130114
    131     tr_sharedLock( s );
     115    tr_globalLock( s->h );
    132116
    133117    if( port == s->bindPort )
    134118    {
    135         tr_sharedUnlock( s );
     119        tr_globalUnlock( s->h );
    136120        return;
    137121    }
     
    166150    }
    167151
    168     tr_sharedUnlock( s );
     152    tr_globalUnlock( s->h );
    169153}
    170154
     
    238222    tr_shared * s = vs;
    239223
    240     tr_sharedLock( s );
     224    tr_globalLock( s->h );
    241225
    242226    /* NAT-PMP and UPnP pulses */
     
    250234    AcceptPeers( s );
    251235
    252     tr_sharedUnlock( s );
     236    tr_globalUnlock( s->h );
    253237
    254238    return TRUE;
  • trunk/libtransmission/shared.h

    r3121 r3254  
    4040
    4141/***********************************************************************
    42  * tr_sharedLock, tr_sharedUnlock
    43  ***********************************************************************
    44  * Gets / releases exclusive access to ressources used by the shared
    45  * thread
    46  **********************************************************************/
    47 void          tr_sharedLock           ( tr_shared * );
    48 void          tr_sharedUnlock         ( tr_shared * );
    49 
    50 /***********************************************************************
    5142 * tr_sharedSetPort
    5243 ***********************************************************************
  • trunk/libtransmission/torrent.c

    r3233 r3254  
    9191tr_torrentLock( const tr_torrent * tor )
    9292{
    93     tr_lockLock ( (tr_lock*)tor->lock );
     93    tr_globalLock( tor->handle );
    9494}
    9595
     
    9797tr_torrentUnlock( const tr_torrent * tor )
    9898{
    99     tr_lockUnlock ( (tr_lock*)tor->lock );
     99    tr_globalUnlock( tor->handle );
    100100}
    101101
     
    300300    tor->info.flags |= flags;
    301301
    302     tr_sharedLock( h->shared );
     302    tr_globalLock( h );
    303303
    304304    tor->destination = tr_strdup( destination );
     
    356356    tr_torrentInitFilePieces( tor );
    357357
    358     tor->lock = tr_lockNew( );
    359 
    360358    tor->upload         = tr_rcInit();
    361359    tor->download       = tr_rcInit();
     
    365363                                  info->hash, SHA_DIGEST_LENGTH,
    366364                                  NULL );
    367  
    368     tr_sharedUnlock( h->shared );
    369365
    370366    tr_peerMgrAddTorrent( h->peerMgr, tor );
     
    408404    tor->trackerSubscription = tr_trackerSubscribe( tor->tracker, onTrackerResponse, tor );
    409405
    410     tr_sharedLock( h->shared );
    411406    tor->next = h->torrentList;
    412407    h->torrentList = tor;
    413408    h->torrentCount++;
    414     tr_sharedUnlock( h->shared );
     409
     410    tr_globalUnlock( h );
    415411
    416412    tr_ioRecheckAdd( tor, recheckDoneCB, tor->runStatus );
     
    1000996    assert( tor->runStatus == TR_RUN_STOPPED );
    1001997
    1002     tr_sharedLock( h->shared );
     998    tr_globalLock( h );
    1003999
    10041000    tr_peerMgrRemoveTorrent( h->peerMgr, tor->info.hash );
    10051001
    1006     tr_lockFree( tor->lock );
    10071002    tr_cpClose( tor->completion );
    10081003
     
    10351030    tr_free( tor );
    10361031
    1037     tr_sharedUnlock( h->shared );
     1032    tr_globalUnlock( h );
    10381033}
    10391034
  • trunk/libtransmission/transmission.c

    r3217 r3254  
    122122        return NULL;
    123123
     124    h->lock = tr_lockNew( );
     125
    124126    h->encryptionMode = TR_ENCRYPTION_PREFERRED;
    125127
     
    152154
    153155    return h;
     156}
     157
     158/***
     159****
     160***/
     161
     162void
     163tr_globalLock( struct tr_handle * handle )
     164{
     165    tr_lockLock( handle->lock );
     166}
     167
     168void
     169tr_globalUnlock( struct tr_handle * handle )
     170{
     171    tr_lockUnlock( handle->lock );
     172}
     173
     174int
     175tr_globalIsLocked( const struct tr_handle * handle )
     176{
     177    return tr_lockHave( handle->lock );
    154178}
    155179
     
    174198void tr_natTraversalEnable( tr_handle * h, int enable )
    175199{
    176     tr_sharedLock( h->shared );
     200    tr_globalLock( h );
    177201    tr_sharedTraversalEnable( h->shared, enable );
    178     tr_sharedUnlock( h->shared );
     202    tr_globalUnlock( h );
    179203}
    180204
     
    186210    s = &h->stats[h->statCur];
    187211
    188     tr_sharedLock( h->shared );
     212    tr_globalLock( h );
    189213
    190214    s->natTraversalStatus = tr_sharedTraversalStatus( h->shared );
    191215    s->publicPort = tr_sharedGetPublicPort( h->shared );
    192216
    193     tr_sharedUnlock( h->shared );
     217    tr_globalUnlock( h );
    194218
    195219    return s;
     
    242266    *dl = 0.0;
    243267    *ul = 0.0;
    244     tr_sharedLock( h->shared );
     268    tr_globalLock( h );
    245269    for( tor = h->torrentList; tor; tor = tor->next )
    246270    {
     
    251275        tr_torrentUnlock( tor );
    252276    }
    253     tr_sharedUnlock( h->shared );
     277    tr_globalUnlock( h );
    254278}
    255279
     
    301325    }
    302326
     327    tr_lockFree( h->lock );
    303328    free( h->tag );
    304329    free( h );
Note: See TracChangeset for help on using the changeset viewer.