Changeset 2552


Ignore:
Timestamp:
Jul 30, 2007, 3:27:52 PM (15 years ago)
Author:
charles
Message:

better encapsulation of platform-specific constructs: tr_thread_t, tr_cond_t, tr_lock_t

Location:
trunk/libtransmission
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/choking.c

    r2544 r2552  
    3636struct tr_choking_s
    3737{
    38     tr_lock_t     lock;
     38    tr_lock_t   * lock;
    3939    tr_handle_t * h;
    4040    int           slots;
     
    4848    c->h     = h;
    4949    c->slots = 4242;
    50     tr_lockInit( &c->lock );
     50    c->lock  = tr_lockNew( );
    5151
    5252    return c;
     
    5555void tr_chokingSetLimit( tr_choking_t * c, int limit )
    5656{
    57     tr_lockLock( &c->lock );
     57    tr_lockLock( c->lock );
    5858    if( limit < 0 )
    5959        c->slots = 4242;
     
    6666            100 KB/s -> 14 * 7.14 KB/s */
    6767        c->slots = lrintf( sqrt( 2 * limit ) );
    68     tr_lockUnlock( &c->lock );
     68    tr_lockUnlock( c->lock );
    6969}
    7070
     
    138138    uint64_t now = tr_date();
    139139
    140     tr_lockLock( &c->lock );
     140    tr_lockLock( c->lock );
    141141
    142142    /* Lock all torrents and get the total number of peers */
     
    311311        tr_torrentWriterUnlock( tor );
    312312
    313     tr_lockUnlock( &c->lock );
     313    tr_lockUnlock( c->lock );
    314314}
    315315
    316316void tr_chokingClose( tr_choking_t * c )
    317317{
    318     tr_lockClose( &c->lock );
     318    tr_lockFree( c->lock );
    319319    tr_free( c );
    320320}
  • trunk/libtransmission/fdlimit.c

    r2544 r2552  
    6464typedef struct tr_fd_s
    6565{
    66     tr_lock_t       lock;
    67     tr_cond_t       cond;
     66    tr_lock_t     * lock;
     67    tr_cond_t     * cond;
    6868   
    6969    int             reserved;
     
    101101
    102102    /* Init lock and cond */
    103     tr_lockInit( &gFd->lock );
    104     tr_condInit( &gFd->cond );
     103    gFd->lock = tr_lockNew( );
     104    gFd->cond = tr_condNew( );
    105105
    106106    /* Detect the maximum number of open files or sockets */
     
    144144    uint64_t date;
    145145
    146     tr_lockLock( &gFd->lock );
     146    tr_lockLock( gFd->lock );
    147147
    148148    /* Is it already open? */
     
    159159            /* File is being closed by another thread, wait until
    160160             * it's done before we reopen it */
    161             tr_condWait( &gFd->cond, &gFd->lock );
     161            tr_condWait( gFd->cond, gFd->lock );
    162162            i = -1;
    163163            continue;
     
    210210
    211211        /* All used! Wait a bit and try again */
    212         tr_condWait( &gFd->cond, &gFd->lock );
     212        tr_condWait( gFd->cond, gFd->lock );
    213213    }
    214214
     
    216216    if( ( ret = OpenFile( winner, folder, name, write ) ) )
    217217    {
    218         tr_lockUnlock( &gFd->lock );
     218        tr_lockUnlock( gFd->lock );
    219219        return ret;
    220220    }
     
    226226    gFd->open[winner].status = STATUS_USED;
    227227    gFd->open[winner].date   = tr_date();
    228     tr_lockUnlock( &gFd->lock );
     228    tr_lockUnlock( gFd->lock );
    229229   
    230230    return gFd->open[winner].file;
     
    237237{
    238238    int i;
    239     tr_lockLock( &gFd->lock );
     239    tr_lockLock( gFd->lock );
    240240
    241241    for( i = 0; i < TR_MAX_OPEN_FILES; i++ )
     
    248248    }
    249249   
    250     tr_condSignal( &gFd->cond );
    251     tr_lockUnlock( &gFd->lock );
     250    tr_condSignal( gFd->cond );
     251    tr_lockUnlock( gFd->lock );
    252252}
    253253
     
    259259    int i;
    260260
    261     tr_lockLock( &gFd->lock );
     261    tr_lockLock( gFd->lock );
    262262
    263263    for( i = 0; i < TR_MAX_OPEN_FILES; i++ )
     
    274274    }
    275275
    276     tr_lockUnlock( &gFd->lock );
     276    tr_lockUnlock( gFd->lock );
    277277}
    278278
     
    334334    int s = -1;
    335335
    336     tr_lockLock( &gFd->lock );
     336    tr_lockLock( gFd->lock );
    337337
    338338    if( priority && gFd->reserved >= TR_RESERVED_FDS )
     
    351351            gFd->normal++;
    352352    }
    353     tr_lockUnlock( &gFd->lock );
     353    tr_lockUnlock( gFd->lock );
    354354
    355355    return s;
     
    362362    struct sockaddr_in sock;
    363363
    364     tr_lockLock( &gFd->lock );
     364    tr_lockLock( gFd->lock );
    365365    if( gFd->normal < gFd->normalMax )
    366366    {
     
    381381        gFd->normal++;
    382382    }
    383     tr_lockUnlock( &gFd->lock );
     383    tr_lockUnlock( gFd->lock );
    384384
    385385    return s;
     
    391391void tr_fdSocketClose( int s )
    392392{
    393     tr_lockLock( &gFd->lock );
     393    tr_lockLock( gFd->lock );
    394394#ifdef BEOS_NETSERVER
    395395    closesocket( s );
     
    401401    else
    402402        gFd->normal--;
    403     tr_lockUnlock( &gFd->lock );
     403    tr_lockUnlock( gFd->lock );
    404404}
    405405
     
    409409void tr_fdClose()
    410410{
    411     tr_lockClose( &gFd->lock );
    412     tr_condClose( &gFd->cond );
     411    tr_lockFree( gFd->lock );
     412    tr_condFree( gFd->cond );
    413413    free( gFd );
    414414}
     
    505505    while( file->status & STATUS_CLOSING )
    506506    {
    507         tr_condWait( &gFd->cond, &gFd->lock );
     507        tr_condWait( gFd->cond, gFd->lock );
    508508    }
    509509    if( file->status & STATUS_INVALID )
     
    519519    tr_dbg( "Closing %s in %s (%d)", file->name, file->folder, file->write );
    520520    file->status = STATUS_CLOSING;
    521     tr_lockUnlock( &gFd->lock );
     521    tr_lockUnlock( gFd->lock );
    522522    close( file->file );
    523     tr_lockLock( &gFd->lock );
     523    tr_lockLock( gFd->lock );
    524524    file->status = STATUS_INVALID;
    525     tr_condSignal( &gFd->cond );
    526 }
    527 
     525    tr_condSignal( gFd->cond );
     526}
     527
  • trunk/libtransmission/internal.h

    r2549 r2552  
    194194    run_status_t      runStatus;
    195195    cp_status_t       cpStatus;
    196     tr_thread_t       thread;
    197     tr_rwlock_t       lock;
     196    tr_thread_t     * thread;
     197    tr_rwlock_t     * lock;
    198198
    199199    tr_tracker_t    * tracker;
  • trunk/libtransmission/list.h

    r2310 r2552  
    2424tr_list_t*  tr_list_prepend     ( tr_list_t*, void * data );
    2525tr_list_t*  tr_list_remove_data ( tr_list_t*, const void * data );
    26 tr_list_t*  tr_list_pop         ( tr_list_t*, void ** setme );
    2726
    2827typedef int (*TrListCompareFunc)(const void * a, const void * b);
  • trunk/libtransmission/makemeta.c

    r2544 r2552  
    408408static tr_metainfo_builder_t * queue = NULL;
    409409
    410 static int workerIsRunning = 0;
    411 
    412 static tr_thread_t workerThread;
     410static tr_thread_t * workerThread = NULL;
    413411
    414412static tr_lock_t* getQueueLock( tr_handle_t * h )
     
    417415
    418416    tr_sharedLock( h->shared );
    419     if( lock == NULL )
    420     {
    421         lock = tr_new0( tr_lock_t, 1 );
    422         tr_lockInit( lock );
    423     }
     417    if( !lock )
     418         lock = tr_lockNew( );
    424419    tr_sharedUnlock( h->shared );
    425420
     
    451446    }
    452447
    453     workerIsRunning = 0;
     448    workerThread = NULL;
    454449}
    455450
     
    481476    builder->nextBuilder = queue;
    482477    queue = builder;
    483     if( !workerIsRunning ) {
    484         workerIsRunning = 1;
    485         tr_threadCreate( &workerThread, workerFunc, builder->handle, "makeMeta" );
    486     }
     478    if( !workerThread )
     479         workerThread = tr_threadNew( workerFunc, builder->handle, "makeMeta" );
    487480    tr_lockUnlock( lock );
    488481}
  • trunk/libtransmission/net.c

    r2544 r2552  
    5757}
    5858
    59 static tr_thread_t  resolveThread;
    60 static tr_lock_t    resolveLock;
    61 static tr_cond_t    resolveCond;
    62 static volatile int resolveDie;
     59static tr_thread_t  * resolveThread;
     60static tr_lock_t    * resolveLock;
     61static tr_cond_t    * resolveCond;
     62static volatile int   resolveDie;
    6363static tr_resolve_t * resolveQueue;
    6464
     
    8686    resolveDie   = 0;
    8787    resolveQueue = NULL;
    88     tr_lockInit( &resolveLock );
    89     tr_condInit( &resolveCond );
    90     tr_threadCreate( &resolveThread, resolveFunc, NULL, "resolve" );
     88    resolveLock = tr_lockNew( );
     89    resolveCond = tr_condNew( );
     90    resolveThread = tr_threadNew( resolveFunc, NULL, "resolve" );
    9191}
    9292
     
    100100void tr_netResolveThreadClose()
    101101{
    102     tr_lockLock( &resolveLock );
     102    tr_lockLock( resolveLock );
    103103    resolveDie = 1;
    104     tr_lockUnlock( &resolveLock );
    105     tr_condSignal( &resolveCond );
     104    tr_lockUnlock( resolveLock );
     105    tr_condSignal( resolveCond );
    106106    tr_wait( 200 );
    107107}
     
    114114tr_resolve_t * tr_netResolveInit( const char * address )
    115115{
    116     tr_resolve_t * r;
    117 
    118     r           = malloc( sizeof( tr_resolve_t ) );
     116    tr_resolve_t * r = tr_new0( tr_resolve_t, 1 );
    119117    r->status   = TR_NET_WAIT;
    120118    r->address  = strdup( address );
     
    122120    r->next     = NULL;
    123121
    124     tr_lockLock( &resolveLock );
     122    tr_lockLock( resolveLock );
    125123    if( !resolveQueue )
    126124    {
     
    133131        iter->next = r;
    134132    }
    135     tr_lockUnlock( &resolveLock );
    136     tr_condSignal( &resolveCond );
     133    tr_lockUnlock( resolveLock );
     134    tr_condSignal( resolveCond );
    137135
    138136    return r;
     
    148146    tr_tristate_t ret;
    149147
    150     tr_lockLock( &resolveLock );
     148    tr_lockLock( resolveLock );
    151149    ret = r->status;
    152150    if( ret == TR_NET_OK )
     
    154152        *addr = r->addr;
    155153    }
    156     tr_lockUnlock( &resolveLock );
     154    tr_lockUnlock( resolveLock );
    157155
    158156    return ret;
     
    197195    struct hostent * host;
    198196
    199     tr_lockLock( &resolveLock );
     197    tr_lockLock( resolveLock );
    200198
    201199    while( !resolveDie )
     
    203201        if( !( r = resolveQueue ) )
    204202        {
    205             tr_condWait( &resolveCond, &resolveLock );
     203            tr_condWait( resolveCond, resolveLock );
    206204            continue;
    207205        }
    208206
    209207        /* Blocking resolution */
    210         tr_lockUnlock( &resolveLock );
     208        tr_lockUnlock( resolveLock );
    211209        host = gethostbyname( r->address );
    212         tr_lockLock( &resolveLock );
     210        tr_lockLock( resolveLock );
    213211
    214212        if( host )
     
    227225
    228226    /* Clean up  */
    229     tr_lockUnlock( &resolveLock );
    230     tr_lockClose( &resolveLock );
     227    tr_lockUnlock( resolveLock );
     228    tr_lockFree( resolveLock );
     229    resolveLock = NULL;
    231230    while( ( r = resolveQueue ) )
    232231    {
  • trunk/libtransmission/net.h

    r2343 r2552  
    3535void           tr_netResolveThreadInit();
    3636void           tr_netResolveThreadClose();
    37 tr_resolve_t * tr_netResolveInit( const char * );
     37tr_resolve_t * tr_netResolveInit( const char * address );
    3838tr_tristate_t  tr_netResolvePulse( tr_resolve_t *, struct in_addr * );
    3939void           tr_netResolveClose( tr_resolve_t * );
  • trunk/libtransmission/platform.c

    r2544 r2552  
    3131  #include <fs_info.h>
    3232  #include <FindDirectory.h>
    33 #endif
     33  #include <kernel/OS.h>
     34  #define BEOS_MAX_THREADS 256
     35#else
     36  #include <pthread.h>
     37#endif
     38
    3439#include <sys/types.h>
    3540#include <dirent.h>
     
    3843
    3944#include "transmission.h"
     45#include "utils.h"
     46
     47/***
     48****  THREADS
     49***/
     50
     51struct tr_thread_s
     52{
     53    void          (* func ) ( void * );
     54    void           * arg;
     55    char           * name;
     56
     57#ifdef SYS_BEOS
     58    thread_id        thread;
     59#else
     60    pthread_t        thread;
     61#endif
     62
     63};
     64
     65static void
     66ThreadFunc( void * _t )
     67{
     68    tr_thread_t * t = _t;
     69    char* name = tr_strdup( t->name );
     70
     71#ifdef SYS_BEOS
     72    /* This is required because on BeOS, SIGINT is sent to each thread,
     73       which kills them not nicely */
     74    signal( SIGINT, SIG_IGN );
     75#endif
     76
     77    tr_dbg( "Thread '%s' started", name );
     78    t->func( t->arg );
     79    tr_dbg( "Thread '%s' exited", name );
     80    tr_free( name );
     81}
     82
     83tr_thread_t *
     84tr_threadNew( void (*func)(void *),
     85              void * arg,
     86              const char * name )
     87{
     88    tr_thread_t * t = tr_new0( tr_thread_t, 1 );
     89    t->func = func;
     90    t->arg  = arg;
     91    t->name = tr_strdup( name );
     92
     93#ifdef SYS_BEOS
     94    t->thread = spawn_thread( (void*)ThreadFunc, name, B_NORMAL_PRIORITY, t );
     95    resume_thread( t->thread );
     96#else
     97    pthread_create( &t->thread, NULL, (void * (*) (void *)) ThreadFunc, t );
     98#endif
     99
     100    return t;
     101}
     102
     103void
     104tr_threadJoin( tr_thread_t * t )
     105{
     106    if( t != NULL )
     107    {
     108#ifdef SYS_BEOS
     109        long exit;
     110        wait_for_thread( t->thread, &exit );
     111#else
     112        pthread_join( t->thread, NULL );
     113#endif
     114
     115        tr_dbg( "Thread '%s' joined", t->name );
     116        tr_free( t->name );
     117        t->name = NULL;
     118        t->func = NULL;
     119        tr_free( t );
     120    }
     121}
     122
     123/***
     124****  LOCKS
     125***/
     126
     127struct tr_lock_s
     128{
     129#ifdef SYS_BEOS
     130    sem_id lock;
     131#else
     132    pthread_mutex_t lock;
     133#endif
     134};
     135
     136tr_lock_t*
     137tr_lockNew( void )
     138{
     139    tr_lock_t * l = tr_new0( tr_lock_t, 1 );
     140
     141#ifdef SYS_BEOS
     142    l->lock = create_sem( 1, "" );
     143#else
     144    pthread_mutex_init( &l->lock, NULL );
     145#endif
     146
     147    return l;
     148}
     149
     150void
     151tr_lockFree( tr_lock_t * l )
     152{
     153#ifdef SYS_BEOS
     154    delete_sem( l->lock );
     155#else
     156    pthread_mutex_destroy( &l->lock );
     157#endif
     158    tr_free( l );
     159}
     160
     161int
     162tr_lockTryLock( tr_lock_t * l )
     163{
     164#ifdef SYS_BEOS
     165    return acquire_sem_etc( l->lock, 1, B_RELATIVE_TIMEOUT, 0 );
     166#else
     167    /* success on zero! */
     168    return pthread_mutex_trylock( &l->lock );
     169#endif
     170}
     171
     172void
     173tr_lockLock( tr_lock_t * l )
     174{
     175#ifdef SYS_BEOS
     176    acquire_sem( l->lock );
     177#else
     178    pthread_mutex_lock( &l->lock );
     179#endif
     180}
     181
     182void
     183tr_lockUnlock( tr_lock_t * l )
     184{
     185#ifdef SYS_BEOS
     186    release_sem( l->lock );
     187#else
     188    pthread_mutex_unlock( &l->lock );
     189#endif
     190}
     191
     192/***
     193****  RW LOCK
     194***/
     195
     196struct tr_rwlock_s
     197{
     198    tr_lock_t * lock;
     199    tr_cond_t * readCond;
     200    tr_cond_t * writeCond;
     201    size_t readCount;
     202    size_t wantToRead;
     203    size_t wantToWrite;
     204    int haveWriter;
     205};
     206
     207static void
     208tr_rwSignal( tr_rwlock_t * rw )
     209{
     210  if ( rw->wantToWrite )
     211    tr_condSignal( rw->writeCond );
     212  else if ( rw->wantToRead )
     213    tr_condBroadcast( rw->readCond );
     214}
     215
     216tr_rwlock_t*
     217tr_rwNew ( void )
     218{
     219    tr_rwlock_t * rw = tr_new0( tr_rwlock_t, 1 );
     220    rw->lock = tr_lockNew( );
     221    rw->readCond = tr_condNew( );
     222    rw->writeCond = tr_condNew( );
     223    return rw;
     224}
     225
     226void
     227tr_rwReaderLock( tr_rwlock_t * rw )
     228{
     229    tr_lockLock( rw->lock );
     230    rw->wantToRead++;
     231    while( rw->haveWriter || rw->wantToWrite )
     232        tr_condWait( rw->readCond, rw->lock );
     233    rw->wantToRead--;
     234    rw->readCount++;
     235    tr_lockUnlock( rw->lock );
     236}
     237
     238int
     239tr_rwReaderTrylock( tr_rwlock_t * rw )
     240{
     241    int ret = FALSE;
     242    tr_lockLock( rw->lock );
     243    if ( !rw->haveWriter && !rw->wantToWrite ) {
     244        rw->readCount++;
     245        ret = TRUE;
     246    }
     247    tr_lockUnlock( rw->lock );
     248    return ret;
     249
     250}
     251
     252void
     253tr_rwReaderUnlock( tr_rwlock_t * rw )
     254{
     255    tr_lockLock( rw->lock );
     256    --rw->readCount;
     257    if( !rw->readCount )
     258        tr_rwSignal( rw );
     259    tr_lockUnlock( rw->lock );
     260}
     261
     262void
     263tr_rwWriterLock( tr_rwlock_t * rw )
     264{
     265    tr_lockLock( rw->lock );
     266    rw->wantToWrite++;
     267    while( rw->haveWriter || rw->readCount )
     268        tr_condWait( rw->writeCond, rw->lock );
     269    rw->wantToWrite--;
     270    rw->haveWriter = TRUE;
     271    tr_lockUnlock( rw->lock );
     272}
     273
     274int
     275tr_rwWriterTrylock( tr_rwlock_t * rw )
     276{
     277    int ret = FALSE;
     278    tr_lockLock( rw->lock );
     279    if( !rw->haveWriter && !rw->readCount )
     280        ret = rw->haveWriter = TRUE;
     281    tr_lockUnlock( rw->lock );
     282    return ret;
     283}
     284void
     285tr_rwWriterUnlock( tr_rwlock_t * rw )
     286{
     287    tr_lockLock( rw->lock );
     288    rw->haveWriter = FALSE;
     289    tr_rwSignal( rw );
     290    tr_lockUnlock( rw->lock );
     291}
     292
     293void
     294tr_rwFree( tr_rwlock_t * rw )
     295{
     296    tr_condFree( rw->writeCond );
     297    tr_condFree( rw->readCond );
     298    tr_lockFree( rw->lock );
     299    tr_free( rw );
     300}
     301
     302/***
     303****  COND
     304***/
     305
     306struct tr_cond_s
     307{
     308#ifdef SYS_BEOS
     309    sem_id sem;
     310    thread_id theads[BEOS_MAX_THREADS];
     311    int start, end;
     312#else
     313    pthread_cond_t cond;
     314#endif
     315};
     316
     317tr_cond_t*
     318tr_condNew( void )
     319{
     320    tr_cond_t * c = tr_new0( tr_cond_t, 1 );
     321#ifdef SYS_BEOS
     322    c->sem = create_sem( 1, "" );
     323    c->start = 0;
     324    c->end = 0;
     325#else
     326    pthread_cond_init( &c->cond, NULL );
     327#endif
     328    return c;
     329}
     330
     331void tr_condWait( tr_cond_t * c, tr_lock_t * l )
     332{
     333#ifdef SYS_BEOS
     334    /* Keep track of that thread */
     335    acquire_sem( c->sem );
     336    c->threads[c->end] = find_thread( NULL );
     337    c->end = ( c->end + 1 ) % BEOS_MAX_THREADS;
     338    assert( c->end != c->start ); /* We hit BEOS_MAX_THREADS, arggh */
     339    release_sem( c->sem );
     340
     341    release_sem( *l );
     342    suspend_thread( find_thread( NULL ) ); /* Wait for signal */
     343    acquire_sem( *l );
     344#else
     345    pthread_cond_wait( &c->cond, &l->lock );
     346#endif
     347}
     348
     349#ifdef SYS_BEOS
     350static int condTrySignal( tr_cond_t * c )
     351{
     352    if( c->start == c->end )
     353        return 1;
     354
     355    for( ;; )
     356    {
     357        thread_info info;
     358        get_thread_info( c->threads[c->start], &info );
     359        if( info.state == B_THREAD_SUSPENDED )
     360        {
     361            resume_thread( c->threads[c->start] );
     362            c->start = ( c->start + 1 ) % BEOS_MAX_THREADS;
     363            break;
     364        }
     365        /* The thread is not suspended yet, which can happen since
     366         * tr_condWait does not atomically suspends after releasing
     367         * the semaphore. Wait a bit and try again. */
     368        snooze( 5000 );
     369    }
     370    return 0;
     371}
     372#endif
     373void tr_condSignal( tr_cond_t * c )
     374{
     375#ifdef SYS_BEOS
     376    acquire_sem( c->sem );
     377    condTrySignal( c );
     378    release_sem( c->sem );
     379#else
     380    pthread_cond_signal( &c->cond );
     381#endif
     382}
     383void tr_condBroadcast( tr_cond_t * c )
     384{
     385#ifdef SYS_BEOS
     386    acquire_sem( c->sem );
     387    while( !condTrySignal( c ) );
     388    release_sem( c->sem );
     389#else
     390    pthread_cond_broadcast( &c->cond );
     391#endif
     392}
     393
     394void
     395tr_condFree( tr_cond_t * c )
     396{
     397#ifdef SYS_BEOS
     398    delete_sem( c->sem );
     399#else
     400    pthread_cond_destroy( &c->cond );
     401#endif
     402    tr_free( c );
     403}
     404
     405
     406/***
     407****  PATHS
     408***/
    40409
    41410#if !defined( SYS_BEOS ) && !defined( __AMIGAOS4__ )
     
    205574}
    206575
    207 static void ThreadFunc( void * _t )
    208 {
    209     tr_thread_t * t = _t;
    210     char* name = tr_strdup( t->name );
    211 
    212 #ifdef SYS_BEOS
    213     /* This is required because on BeOS, SIGINT is sent to each thread,
    214        which kills them not nicely */
    215     signal( SIGINT, SIG_IGN );
    216 #endif
    217 
    218     tr_dbg( "Thread '%s' started", name );
    219     t->func( t->arg );
    220     tr_dbg( "Thread '%s' exited", name );
    221     tr_free( name );
    222 }
    223 
    224 void tr_threadCreate( tr_thread_t * t,
    225                       void (*func)(void *), void * arg,
    226                       const char * name )
    227 {
    228     t->func = func;
    229     t->arg  = arg;
    230     t->name = tr_strdup( name );
    231 #ifdef SYS_BEOS
    232     t->thread = spawn_thread( (void *) ThreadFunc, name,
    233                               B_NORMAL_PRIORITY, t );
    234     resume_thread( t->thread );
    235 #else
    236     pthread_create( &t->thread, NULL, (void * (*) (void *)) ThreadFunc, t );
    237 #endif
    238 }
    239 
    240 const tr_thread_t THREAD_EMPTY = { NULL, NULL, NULL, 0 };
    241 
    242 void tr_threadJoin( tr_thread_t * t )
    243 {
    244     if( t->func != NULL )
    245     {
    246 #ifdef SYS_BEOS
    247         long exit;
    248         wait_for_thread( t->thread, &exit );
    249 #else
    250         pthread_join( t->thread, NULL );
    251 #endif
    252         tr_dbg( "Thread '%s' joined", t->name );
    253         tr_free( t->name );
    254         t->name = NULL;
    255         t->func = NULL;
    256     }
    257 }
    258 
    259 void tr_lockInit( tr_lock_t * l )
    260 {
    261 #ifdef SYS_BEOS
    262     *l = create_sem( 1, "" );
    263 #else
    264     pthread_mutex_init( l, NULL );
    265 #endif
    266 }
    267 
    268 void tr_lockClose( tr_lock_t * l )
    269 {
    270 #ifdef SYS_BEOS
    271     delete_sem( *l );
    272 #else
    273     pthread_mutex_destroy( l );
    274 #endif
    275 }
    276 
    277 int tr_lockTryLock( tr_lock_t * l )
    278 {
    279 #ifdef SYS_BEOS
    280     return acquire_sem_etc( *l, 1, B_RELATIVE_TIMEOUT, 0 );
    281 #else
    282     /* success on zero! */
    283     return pthread_mutex_trylock( l );
    284 #endif
    285 }
    286 
    287 void tr_lockLock( tr_lock_t * l )
    288 {
    289 #ifdef SYS_BEOS
    290     acquire_sem( *l );
    291 #else
    292     pthread_mutex_lock( l );
    293 #endif
    294 }
    295 
    296 void tr_lockUnlock( tr_lock_t * l )
    297 {
    298 #ifdef SYS_BEOS
    299     release_sem( *l );
    300 #else
    301     pthread_mutex_unlock( l );
    302 #endif
    303 }
    304 
    305 
    306 void tr_condInit( tr_cond_t * c )
    307 {
    308 #ifdef SYS_BEOS
    309     c->sem = create_sem( 1, "" );
    310     c->start = 0;
    311     c->end = 0;
    312 #else
    313     pthread_cond_init( c, NULL );
    314 #endif
    315 }
    316 
    317 void tr_condWait( tr_cond_t * c, tr_lock_t * l )
    318 {
    319 #ifdef SYS_BEOS
    320     /* Keep track of that thread */
    321     acquire_sem( c->sem );
    322     c->threads[c->end] = find_thread( NULL );
    323     c->end = ( c->end + 1 ) % BEOS_MAX_THREADS;
    324     assert( c->end != c->start ); /* We hit BEOS_MAX_THREADS, arggh */
    325     release_sem( c->sem );
    326 
    327     release_sem( *l );
    328     suspend_thread( find_thread( NULL ) ); /* Wait for signal */
    329     acquire_sem( *l );
    330 #else
    331     pthread_cond_wait( c, l );
    332 #endif
    333 }
    334 
    335 #ifdef SYS_BEOS
    336 static int condTrySignal( tr_cond_t * c )
    337 {
    338     if( c->start == c->end )
    339         return 1;
    340 
    341     for( ;; )
    342     {
    343         thread_info info;
    344         get_thread_info( c->threads[c->start], &info );
    345         if( info.state == B_THREAD_SUSPENDED )
    346         {
    347             resume_thread( c->threads[c->start] );
    348             c->start = ( c->start + 1 ) % BEOS_MAX_THREADS;
    349             break;
    350         }
    351         /* The thread is not suspended yet, which can happen since
    352          * tr_condWait does not atomically suspends after releasing
    353          * the semaphore. Wait a bit and try again. */
    354         snooze( 5000 );
    355     }
    356     return 0;
    357 }
    358 #endif
    359 void tr_condSignal( tr_cond_t * c )
    360 {
    361 #ifdef SYS_BEOS
    362     acquire_sem( c->sem );
    363     condTrySignal( c );
    364     release_sem( c->sem );
    365 #else
    366     pthread_cond_signal( c );
    367 #endif
    368 }
    369 void tr_condBroadcast( tr_cond_t * c )
    370 {
    371 #ifdef SYS_BEOS
    372     acquire_sem( c->sem );
    373     while( !condTrySignal( c ) );
    374     release_sem( c->sem );
    375 #else
    376     pthread_cond_broadcast( c );
    377 #endif
    378 }
    379 
    380 void tr_condClose( tr_cond_t * c )
    381 {
    382 #ifdef SYS_BEOS
    383     delete_sem( c->sem );
    384 #else
    385     pthread_cond_destroy( c );
    386 #endif
    387 }
    388 
    389 
    390 #if defined( BSD )
     576/***
     577****  SOCKETS
     578***/
     579
     580#ifdef BSD
    391581
    392582#include <sys/types.h>
     
    760950
    761951#endif
    762 
    763 /***
    764 ****
    765 ***/
    766 
    767 static void
    768 tr_rwSignal( tr_rwlock_t * rw )
    769 {
    770   if ( rw->wantToWrite )
    771     tr_condSignal( &rw->writeCond );
    772   else if ( rw->wantToRead )
    773     tr_condBroadcast( &rw->readCond );
    774 }
    775 
    776 void
    777 tr_rwInit ( tr_rwlock_t * rw )
    778 {
    779     memset( rw, 0, sizeof(tr_rwlock_t) );
    780     tr_lockInit( &rw->lock );
    781     tr_condInit( &rw->readCond );
    782     tr_condInit( &rw->writeCond );
    783 }
    784 
    785 void
    786 tr_rwReaderLock( tr_rwlock_t * rw )
    787 {
    788     tr_lockLock( &rw->lock );
    789     rw->wantToRead++;
    790     while( rw->haveWriter || rw->wantToWrite )
    791         tr_condWait( &rw->readCond, &rw->lock );
    792     rw->wantToRead--;
    793     rw->readCount++;
    794     tr_lockUnlock( &rw->lock );
    795 }
    796 
    797 int
    798 tr_rwReaderTrylock( tr_rwlock_t * rw )
    799 {
    800     int ret = FALSE;
    801     tr_lockLock( &rw->lock );
    802     if ( !rw->haveWriter && !rw->wantToWrite ) {
    803         rw->readCount++;
    804         ret = TRUE;
    805     }
    806     tr_lockUnlock( &rw->lock );
    807     return ret;
    808 
    809 }
    810 
    811 void
    812 tr_rwReaderUnlock( tr_rwlock_t * rw )
    813 {
    814     tr_lockLock( &rw->lock );
    815     --rw->readCount;
    816     if( !rw->readCount )
    817         tr_rwSignal( rw );
    818     tr_lockUnlock( &rw->lock );
    819 }
    820 
    821 void
    822 tr_rwWriterLock( tr_rwlock_t * rw )
    823 {
    824     tr_lockLock( &rw->lock );
    825     rw->wantToWrite++;
    826     while( rw->haveWriter || rw->readCount )
    827         tr_condWait( &rw->writeCond, &rw->lock );
    828     rw->wantToWrite--;
    829     rw->haveWriter = TRUE;
    830     tr_lockUnlock( &rw->lock );
    831 }
    832 
    833 int
    834 tr_rwWriterTrylock( tr_rwlock_t * rw )
    835 {
    836     int ret = FALSE;
    837     tr_lockLock( &rw->lock );
    838     if( !rw->haveWriter && !rw->readCount )
    839         ret = rw->haveWriter = TRUE;
    840     tr_lockUnlock( &rw->lock );
    841     return ret;
    842 }
    843 void
    844 tr_rwWriterUnlock( tr_rwlock_t * rw )
    845 {
    846     tr_lockLock( &rw->lock );
    847     rw->haveWriter = FALSE;
    848     tr_rwSignal( rw );
    849     tr_lockUnlock( &rw->lock );
    850 }
    851 
    852 void
    853 tr_rwClose( tr_rwlock_t * rw )
    854 {
    855     tr_condClose( &rw->writeCond );
    856     tr_condClose( &rw->readCond );
    857     tr_lockClose( &rw->lock );
    858 }
  • trunk/libtransmission/platform.h

    r2323 r2552  
    2323 *****************************************************************************/
    2424#ifndef TR_PLATFORM_H
    25 #define TR_PLATFORM_H 1
     25#define TR_PLATFORM_H
    2626
    27 #ifdef SYS_BEOS
    28   #include <kernel/OS.h>
    29   #define BEOS_MAX_THREADS 256
    30   typedef thread_id tr_thread_id_t;
    31   typedef sem_id    tr_lock_t;
    32   typedef struct
    33   {
    34       sem_id sem;
    35       thread_id threads[BEOS_MAX_THREADS];
    36       int start;
    37       int end;
    38   } tr_cond_t;
    39 #else
    40   #include <pthread.h>
    41   typedef pthread_t       tr_thread_id_t;
    42   typedef pthread_mutex_t tr_lock_t;
    43   typedef pthread_cond_t  tr_cond_t;
    44 #endif
    45 typedef struct tr_thread_s
    46 {
    47     void          (* func ) ( void * );
    48     void           * arg;
    49     char           * name;
    50     tr_thread_id_t thread;
    51 }
    52 tr_thread_t;
     27typedef struct tr_lock_s   tr_lock_t;
     28typedef struct tr_cond_s   tr_cond_t;
     29typedef struct tr_thread_s tr_thread_t;
    5330
    5431const char * tr_getHomeDirectory( void );
     
    5633const char * tr_getTorrentsDirectory( void );
    5734
    58 /**
    59  * When instantiating a thread with a deferred call to tr_threadCreate(),
    60  * initializing it to THREAD_EMPTY makes calls tr_threadJoin() safe.
    61  */
    62 const tr_thread_t THREAD_EMPTY;
     35tr_thread_t*  tr_threadNew  ( void (*func)(void *), void * arg, const char * name );
     36void          tr_threadJoin ( tr_thread_t * );
    6337
    64 void tr_threadCreate ( tr_thread_t *, void (*func)(void *),
    65                        void * arg, const char * name );
    66 void tr_threadJoin   ( tr_thread_t * );
    67 void tr_lockInit     ( tr_lock_t * );
    68 void tr_lockClose    ( tr_lock_t * );
    69 int  tr_lockTryLock  ( tr_lock_t * );
    70 void tr_lockLock     ( tr_lock_t * );
    71 void tr_lockUnlock   ( tr_lock_t * );
     38tr_lock_t * tr_lockNew        ( void );
     39void        tr_lockFree       ( tr_lock_t * );
     40int         tr_lockTryLock    ( tr_lock_t * );
     41void        tr_lockLock       ( tr_lock_t * );
     42void        tr_lockUnlock     ( tr_lock_t * );
    7243
    73 void tr_condInit      ( tr_cond_t * );
    74 void tr_condSignal    ( tr_cond_t * );
    75 void tr_condBroadcast ( tr_cond_t * );
    76 void tr_condClose    ( tr_cond_t * );
    77 void tr_condWait      ( tr_cond_t *, tr_lock_t * );
     44tr_cond_t * tr_condNew       ( void );
     45void        tr_condFree      ( tr_cond_t * );
     46void        tr_condSignal    ( tr_cond_t * );
     47void        tr_condBroadcast ( tr_cond_t * );
     48void        tr_condWait      ( tr_cond_t *, tr_lock_t * );
    7849
    7950/***
     
    8253***/
    8354
    84 typedef struct tr_rwlock_s
    85 {
    86     tr_lock_t lock;
    87     tr_cond_t readCond;
    88     tr_cond_t writeCond;
    89     size_t readCount;
    90     size_t wantToRead;
    91     size_t wantToWrite;
    92     int haveWriter;
    93 }
    94 tr_rwlock_t;
     55typedef struct tr_rwlock_s tr_rwlock_t;
    9556
    96 void  tr_rwInit          ( tr_rwlock_t * );
    97 void  tr_rwClose         ( tr_rwlock_t * );
    98 void  tr_rwReaderLock    ( tr_rwlock_t * );
    99 int   tr_rwReaderTrylock ( tr_rwlock_t * );
    100 void  tr_rwReaderUnlock  ( tr_rwlock_t * );
    101 void  tr_rwWriterLock    ( tr_rwlock_t * );
    102 int   tr_rwWriterTrylock ( tr_rwlock_t * );
    103 void  tr_rwWriterUnlock  ( tr_rwlock_t * );
     57tr_rwlock_t*  tr_rwNew           ( void );
     58void          tr_rwFree          ( tr_rwlock_t * );
     59void          tr_rwReaderLock    ( tr_rwlock_t * );
     60int           tr_rwReaderTrylock ( tr_rwlock_t * );
     61void          tr_rwReaderUnlock  ( tr_rwlock_t * );
     62void          tr_rwWriterLock    ( tr_rwlock_t * );
     63int           tr_rwWriterTrylock ( tr_rwlock_t * );
     64void          tr_rwWriterUnlock  ( tr_rwlock_t * );
    10465
    10566
  • trunk/libtransmission/ratecontrol.c

    r2544 r2552  
    4242struct tr_ratecontrol_s
    4343{
    44     tr_rwlock_t lock;
     44    tr_rwlock_t * lock;
    4545    int limit;
    4646    int newest;
     
    7878    tr_ratecontrol_t * r = tr_new0( tr_ratecontrol_t, 1 );
    7979    r->limit = 0;
    80     tr_rwInit( &r->lock );
     80    r->lock = tr_rwNew( );
    8181    return r;
    8282}
     
    8686{
    8787    tr_rcReset( r );
    88     tr_rwClose( &r->lock );
     88    tr_rwFree( r->lock );
    8989    tr_free( r );
    9090}
     
    9898{
    9999    int ret;
    100     tr_rwReaderLock( (tr_rwlock_t*)&r->lock );
     100    tr_rwReaderLock( (tr_rwlock_t*)r->lock );
    101101
    102102    ret = rateForInterval( r, SHORT_INTERVAL_MSEC ) < r->limit;
    103103
    104     tr_rwReaderUnlock( (tr_rwlock_t*)&r->lock );
     104    tr_rwReaderUnlock( (tr_rwlock_t*)r->lock );
    105105    return ret;
    106106}
     
    110110{
    111111    float ret;
    112     tr_rwReaderLock( (tr_rwlock_t*)&r->lock );
     112    tr_rwReaderLock( (tr_rwlock_t*)r->lock );
    113113
    114114    ret = rateForInterval( r, LONG_INTERVAL_MSEC );
    115115
    116     tr_rwReaderUnlock( (tr_rwlock_t*)&r->lock );
     116    tr_rwReaderUnlock( (tr_rwlock_t*)r->lock );
    117117    return ret;
    118118}
     
    130130        return;
    131131   
    132     tr_rwWriterLock( &r->lock );
     132    tr_rwWriterLock( r->lock );
    133133
    134134    now = tr_date ();
     
    141141    }
    142142
    143     tr_rwWriterUnlock( &r->lock );
     143    tr_rwWriterUnlock( r->lock );
    144144}
    145145
     
    147147tr_rcReset( tr_ratecontrol_t * r )
    148148{
    149     tr_rwWriterLock( &r->lock );
     149    tr_rwWriterLock( r->lock );
    150150    r->newest = 0;
    151151    memset( r->transfers, 0, sizeof(tr_transfer_t) * HISTORY_SIZE );
    152     tr_rwWriterUnlock( &r->lock );
     152    tr_rwWriterUnlock( r->lock );
    153153}
    154154
     
    156156tr_rcSetLimit( tr_ratecontrol_t * r, int limit )
    157157{
    158     tr_rwWriterLock( &r->lock );
     158    tr_rwWriterLock( r->lock );
    159159    r->limit = limit;
    160     tr_rwWriterUnlock( &r->lock );
     160    tr_rwWriterUnlock( r->lock );
    161161}
    162162
  • trunk/libtransmission/shared.c

    r2544 r2552  
    4747{
    4848    tr_handle_t  * h;
    49     volatile int die;
    50     tr_thread_t  thread;
    51     tr_lock_t    lock;
     49    volatile int   die;
     50    tr_thread_t  * thread;
     51    tr_lock_t    * lock;
    5252
    5353    /* Incoming connections */
     
    8585    tr_shared_t * s = calloc( 1, sizeof( tr_shared_t ) );
    8686
    87     s->h = h;
    88     tr_lockInit( &s->lock );
    89 
     87    s->h          = h;
     88    s->lock       = tr_lockNew( );
    9089    s->publicPort = -1;
    9190    s->bindPort   = -1;
     
    9493    s->upnp       = tr_upnpInit();
    9594    s->choking    = tr_chokingInit( h );
    96 
    97     /* Launch the thread */
    98     s->die = 0;
    99     tr_threadCreate( &s->thread, SharedLoop, s, "shared" );
     95    s->die        = 0;
     96    s->thread     = tr_threadNew( SharedLoop, s, "shared" );
    10097
    10198    return s;
     
    113110    /* Stop the thread */
    114111    s->die = 1;
    115     tr_threadJoin( &s->thread );
     112    tr_threadJoin( s->thread );
    116113
    117114    /* Clean up */
     
    124121        tr_netClose( s->bindSocket );
    125122    }
    126     tr_lockClose( &s->lock );
     123    tr_lockFree( s->lock );
    127124    tr_natpmpClose( s->natpmp );
    128125    tr_upnpClose( s->upnp );
     
    138135void tr_sharedLock( tr_shared_t * s )
    139136{
    140     tr_lockLock( &s->lock );
     137    tr_lockLock( s->lock );
    141138}
    142139void tr_sharedUnlock( tr_shared_t * s )
    143140{
    144     tr_lockUnlock( &s->lock );
     141    tr_lockUnlock( s->lock );
    145142}
    146143
  • trunk/libtransmission/torrent.c

    r2544 r2552  
    4747tr_torrentReaderLock( const tr_torrent_t * tor )
    4848{
    49     tr_rwReaderLock ( (tr_rwlock_t*)&tor->lock );
     49    tr_rwReaderLock ( (tr_rwlock_t*)tor->lock );
    5050}
    5151
     
    5353tr_torrentReaderUnlock( const tr_torrent_t * tor )
    5454{
    55     tr_rwReaderUnlock ( (tr_rwlock_t*)&tor->lock );
     55    tr_rwReaderUnlock ( (tr_rwlock_t*)tor->lock );
    5656}
    5757
     
    5959tr_torrentWriterLock( tr_torrent_t * tor )
    6060{
    61     tr_rwWriterLock ( &tor->lock );
     61    tr_rwWriterLock ( tor->lock );
    6262}
    6363
     
    6565tr_torrentWriterUnlock( tr_torrent_t * tor )
    6666{
    67     tr_rwWriterUnlock ( &tor->lock );
     67    tr_rwWriterUnlock ( tor->lock );
    6868}
    6969
     
    260260    tr_torrentInitFilePieces( tor );
    261261
    262     tor->thread = THREAD_EMPTY;
    263     tr_rwInit( &tor->lock );
     262    tor->lock = tr_rwNew( );
    264263
    265264    tor->upload         = tr_rcInit();
     
    306305
    307306    snprintf( name, sizeof( name ), "torrent %p (%s)", tor, tor->info.name );
    308     tr_threadCreate( &tor->thread, torrentThreadLoop, tor, name );
     307    tor->thread = tr_threadNew( torrentThreadLoop, tor, name );
    309308}
    310309
     
    10431042    tr_sharedLock( h->shared );
    10441043
    1045     tr_rwClose( &tor->lock );
     1044    tr_rwFree( tor->lock );
    10461045    tr_cpClose( tor->completion );
    10471046
     
    10981097torrentThreadLoop ( void * _tor )
    10991098{
    1100     static tr_lock_t checkFilesLock;
    1101     static int checkFilesLockInited = FALSE;
     1099    static tr_lock_t * checkFilesLock = NULL;
    11021100    tr_torrent_t * tor = _tor;
    11031101
    11041102    /* create the check-files mutex */
    1105     if( !checkFilesLockInited ) {
    1106          checkFilesLockInited = TRUE;
    1107          tr_lockInit( &checkFilesLock );
    1108     }
     1103    if( !checkFilesLock )
     1104         checkFilesLock = tr_lockNew( );
    11091105
    11101106    /* loop until the torrent is being deleted */
     
    11741170        if( tor->uncheckedPieces )
    11751171        {
    1176             if( !tr_lockTryLock( &checkFilesLock ) )
     1172            if( !tr_lockTryLock( checkFilesLock ) )
    11771173            {
    11781174                run_status_t realStatus;
     
    11901186                tr_torrentWriterUnlock( tor );
    11911187
    1192                 tr_lockUnlock( &checkFilesLock );
     1188                tr_lockUnlock( checkFilesLock );
    11931189            }
    11941190            continue;
  • trunk/libtransmission/utils.c

    r2544 r2552  
    5151void tr_msgInit( void )
    5252{
    53     if( NULL == messageLock )
    54     {
    55         messageLock = calloc( 1, sizeof( *messageLock ) );
    56         tr_lockInit( messageLock );
    57     }
     53    if( !messageLock )
     54         messageLock = tr_lockNew( );
    5855}
    5956
Note: See TracChangeset for help on using the changeset viewer.