Changeset 2197


Ignore:
Timestamp:
Jun 25, 2007, 9:52:18 PM (15 years ago)
Author:
charles
Message:

building up our threading tools: implement RW locks

Location:
trunk/libtransmission
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/platform.c

    r2184 r2197  
    213213}
    214214
    215 void tr_threadCreate( tr_thread_t * t, void (*func)(void *), void * arg,
    216                       char * name )
     215void tr_threadCreate( tr_thread_t * t,
     216                      void (*func)(void *), void * arg,
     217                      const char * name )
    217218{
    218219    t->func = func;
    219220    t->arg  = arg;
    220     t->name = strdup( name );
     221    t->name = tr_strdup( name );
    221222#ifdef SYS_BEOS
    222223    t->thread = spawn_thread( (void *) ThreadFunc, name,
     
    232233void tr_threadJoin( tr_thread_t * t )
    233234{
    234     if (t->func != NULL)
     235    if( t->func != NULL )
    235236    {
    236237#ifdef SYS_BEOS
     
    262263#else
    263264    pthread_mutex_destroy( l );
     265#endif
     266}
     267
     268int tr_lockTryLock( tr_lock_t * l )
     269{
     270#ifdef SYS_BEOS
     271    #error how is this done in beos
     272#else
     273    return pthread_mutex_trylock( l );
    264274#endif
    265275}
     
    322332#else
    323333    pthread_cond_signal( c );
     334#endif
     335}
     336void tr_condBroadcast( tr_cond_t * c )
     337{
     338#ifdef SYS_BEOS
     339    #error how is this done in beos
     340#else
     341    pthread_cond_broadcast( c );
    324342#endif
    325343}
     
    703721
    704722#endif
     723
     724/***
     725****
     726***/
     727
     728static void
     729tr_rwSignal( tr_rwlock_t * rw )
     730{
     731  if ( rw->wantToWrite )
     732    tr_condSignal( &rw->writeCond );
     733  else if ( rw->wantToRead )
     734    tr_condBroadcast( &rw->readCond );
     735}
     736
     737void
     738tr_rwInit ( tr_rwlock_t * rw )
     739{
     740    memset( rw, 0, sizeof(tr_rwlock_t) );
     741    tr_lockInit( &rw->lock );
     742    tr_condInit( &rw->readCond );
     743    tr_condInit( &rw->writeCond );
     744}
     745
     746void
     747tr_rwReaderLock( tr_rwlock_t * rw )
     748{
     749    tr_lockLock( &rw->lock );
     750    rw->wantToRead++;
     751    while( rw->haveWriter || rw->wantToWrite )
     752        tr_condWait( &rw->readCond, &rw->lock );
     753    rw->wantToRead--;
     754    rw->readCount++;
     755    tr_lockUnlock( &rw->lock );
     756}
     757
     758int
     759tr_rwReaderTrylock( tr_rwlock_t * rw )
     760{
     761    int ret = FALSE;
     762    tr_lockLock( &rw->lock );
     763    if ( !rw->haveWriter && !rw->wantToWrite ) {
     764        rw->readCount++;
     765        ret = TRUE;
     766    }
     767    tr_lockUnlock( &rw->lock );
     768    return ret;
     769
     770}
     771
     772void
     773tr_rwReaderUnlock( tr_rwlock_t * rw )
     774{
     775    tr_lockLock( &rw->lock );
     776    --rw->readCount;
     777    if( !rw->readCount )
     778        tr_rwSignal( rw );
     779    tr_lockUnlock( &rw->lock );
     780}
     781
     782void
     783tr_rwWriterLock( tr_rwlock_t * rw )
     784{
     785    tr_lockLock( &rw->lock );
     786    rw->wantToWrite++;
     787    while( rw->haveWriter || rw->readCount )
     788        tr_condWait( &rw->writeCond, &rw->lock );
     789    rw->wantToWrite--;
     790    rw->haveWriter = TRUE;
     791    tr_lockUnlock( &rw->lock );
     792}
     793
     794int
     795tr_rwWriterTrylock( tr_rwlock_t * rw )
     796{
     797    int ret = FALSE;
     798    tr_lockLock( &rw->lock );
     799    if( !rw->haveWriter && !rw->readCount )
     800        ret = rw->haveWriter = TRUE;
     801    tr_lockUnlock( &rw->lock );
     802    return ret;
     803}
     804void
     805tr_rwWriterUnlock( tr_rwlock_t * rw )
     806{
     807    tr_lockLock( &rw->lock );
     808    rw->haveWriter = FALSE;
     809    tr_rwSignal( rw );
     810    tr_lockUnlock( &rw->lock );
     811}
     812
     813void
     814tr_rwClose( tr_rwlock_t * rw )
     815{
     816    tr_condClose( &rw->writeCond );
     817    tr_condClose( &rw->readCond );
     818    tr_lockClose( &rw->lock );
     819}
  • trunk/libtransmission/platform.h

    r2184 r2197  
    5656
    5757void tr_threadCreate ( tr_thread_t *, void (*func)(void *),
    58                        void * arg, char * name );
     58                       void * arg, const char * name );
    5959void tr_threadJoin   ( tr_thread_t * );
    6060void tr_lockInit     ( tr_lock_t * );
    6161void tr_lockClose    ( tr_lock_t * );
     62int  tr_lockTryLock  ( tr_lock_t * );
    6263void tr_lockLock     ( tr_lock_t * );
    6364void tr_lockUnlock   ( tr_lock_t * );
    6465
    65 void tr_condInit     ( tr_cond_t * );
    66 void tr_condWait     ( tr_cond_t *, tr_lock_t * );
    67 void tr_condSignal   ( tr_cond_t * );
    68 void tr_condClose    ( tr_cond_t * );
     66void tr_condInit      ( tr_cond_t * );
     67void tr_condSignal    ( tr_cond_t * );
     68void tr_condBroadcast ( tr_cond_t * );
     69void tr_condClose     ( tr_cond_t * );
     70void tr_condWait      ( tr_cond_t *, tr_lock_t * );
     71
     72/***
     73**** RW lock:
     74**** The lock can be had by one writer or any number of readers.
     75***/
     76
     77typedef struct tr_rwlock_s
     78{
     79    tr_lock_t lock;
     80    tr_cond_t readCond;
     81    tr_cond_t writeCond;
     82    size_t readCount;
     83    size_t wantToRead;
     84    size_t wantToWrite;
     85    int haveWriter;
     86}
     87tr_rwlock_t;
     88
     89void  tr_rwInit          ( tr_rwlock_t * );
     90void  tr_rwClose         ( tr_rwlock_t * );
     91void  tr_rwReaderLock    ( tr_rwlock_t * );
     92int   tr_rwReaderTrylock ( tr_rwlock_t * );
     93void  tr_rwReaderUnlock  ( tr_rwlock_t * );
     94void  tr_rwWriterLock    ( tr_rwlock_t * );
     95int   tr_rwWriterTrylock ( tr_rwlock_t * );
     96void  tr_rwWriterUnlock  ( tr_rwlock_t * );
     97
    6998
    7099struct in_addr; /* forward declaration to calm gcc down */
Note: See TracChangeset for help on using the changeset viewer.