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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.