diff options
| -rw-r--r-- | ot_mutex.c | 76 |
1 files changed, 10 insertions, 66 deletions
| @@ -25,65 +25,14 @@ | |||
| 25 | 25 | ||
| 26 | /* Our global all torrents list */ | 26 | /* Our global all torrents list */ |
| 27 | static ot_vector all_torrents[OT_BUCKET_COUNT]; | 27 | static ot_vector all_torrents[OT_BUCKET_COUNT]; |
| 28 | static pthread_mutex_t bucket_mutex[OT_BUCKET_COUNT]; | ||
| 28 | static size_t g_torrent_count; | 29 | static size_t g_torrent_count; |
| 29 | 30 | ||
| 30 | /* Bucket Magic */ | ||
| 31 | static int bucket_locklist[ OT_MAX_THREADS ]; | ||
| 32 | static int bucket_locklist_count = 0; | ||
| 33 | static pthread_mutex_t bucket_mutex; | ||
| 34 | static pthread_cond_t bucket_being_unlocked; | ||
| 35 | |||
| 36 | /* Self pipe from opentracker.c */ | 31 | /* Self pipe from opentracker.c */ |
| 37 | extern int g_self_pipe[2]; | 32 | extern int g_self_pipe[2]; |
| 38 | 33 | ||
| 39 | static int bucket_check( int bucket ) { | ||
| 40 | /* C should come with auto-i ;) */ | ||
| 41 | int i; | ||
| 42 | |||
| 43 | /* No more space to acquire lock to bucket -- should not happen */ | ||
| 44 | if( bucket_locklist_count == OT_MAX_THREADS ) { | ||
| 45 | fprintf( stderr, "More lock requests than mutexes. Consult source code.\n" ); | ||
| 46 | return -1; | ||
| 47 | } | ||
| 48 | |||
| 49 | /* See, if bucket is already locked */ | ||
| 50 | for( i=0; i<bucket_locklist_count; ++i ) | ||
| 51 | if( bucket_locklist[ i ] == bucket ) { | ||
| 52 | stats_issue_event( EVENT_BUCKET_LOCKED, 0, 0 ); | ||
| 53 | return -1; | ||
| 54 | } | ||
| 55 | |||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | |||
| 59 | static void bucket_push( int bucket ) { | ||
| 60 | bucket_locklist[ bucket_locklist_count++ ] = bucket; | ||
| 61 | } | ||
| 62 | |||
| 63 | static void bucket_remove( int bucket ) { | ||
| 64 | int i = 0; | ||
| 65 | |||
| 66 | while( ( i < bucket_locklist_count ) && ( bucket_locklist[ i ] != bucket ) ) | ||
| 67 | ++i; | ||
| 68 | |||
| 69 | if( i == bucket_locklist_count ) { | ||
| 70 | fprintf( stderr, "Request to unlock bucket that was never locked. Consult source code.\n" ); | ||
| 71 | return; | ||
| 72 | } | ||
| 73 | |||
| 74 | for( ; i < bucket_locklist_count - 1; ++i ) | ||
| 75 | bucket_locklist[ i ] = bucket_locklist[ i + 1 ]; | ||
| 76 | |||
| 77 | --bucket_locklist_count; | ||
| 78 | } | ||
| 79 | |||
| 80 | /* Can block */ | ||
| 81 | ot_vector *mutex_bucket_lock( int bucket ) { | 34 | ot_vector *mutex_bucket_lock( int bucket ) { |
| 82 | pthread_mutex_lock( &bucket_mutex ); | 35 | pthread_mutex_lock(bucket_mutex + bucket ); |
| 83 | while( bucket_check( bucket ) ) | ||
| 84 | pthread_cond_wait( &bucket_being_unlocked, &bucket_mutex ); | ||
| 85 | bucket_push( bucket ); | ||
| 86 | pthread_mutex_unlock( &bucket_mutex ); | ||
| 87 | return all_torrents + bucket; | 36 | return all_torrents + bucket; |
| 88 | } | 37 | } |
| 89 | 38 | ||
| @@ -92,11 +41,8 @@ ot_vector *mutex_bucket_lock_by_hash( ot_hash hash ) { | |||
| 92 | } | 41 | } |
| 93 | 42 | ||
| 94 | void mutex_bucket_unlock( int bucket, int delta_torrentcount ) { | 43 | void mutex_bucket_unlock( int bucket, int delta_torrentcount ) { |
| 95 | pthread_mutex_lock( &bucket_mutex ); | 44 | pthread_mutex_unlock(bucket_mutex + bucket); |
| 96 | bucket_remove( bucket ); | ||
| 97 | g_torrent_count += delta_torrentcount; | 45 | g_torrent_count += delta_torrentcount; |
| 98 | pthread_cond_broadcast( &bucket_being_unlocked ); | ||
| 99 | pthread_mutex_unlock( &bucket_mutex ); | ||
| 100 | } | 46 | } |
| 101 | 47 | ||
| 102 | void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ) { | 48 | void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ) { |
| @@ -104,11 +50,7 @@ void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ) { | |||
| 104 | } | 50 | } |
| 105 | 51 | ||
| 106 | size_t mutex_get_torrent_count( ) { | 52 | size_t mutex_get_torrent_count( ) { |
| 107 | size_t torrent_count; | 53 | return g_torrent_count; |
| 108 | pthread_mutex_lock( &bucket_mutex ); | ||
| 109 | torrent_count = g_torrent_count; | ||
| 110 | pthread_mutex_unlock( &bucket_mutex ); | ||
| 111 | return torrent_count; | ||
| 112 | } | 54 | } |
| 113 | 55 | ||
| 114 | /* TaskQueue Magic */ | 56 | /* TaskQueue Magic */ |
| @@ -318,16 +260,18 @@ int64 mutex_workqueue_popresult( int *iovec_entries, struct iovec ** iovec ) { | |||
| 318 | } | 260 | } |
| 319 | 261 | ||
| 320 | void mutex_init( ) { | 262 | void mutex_init( ) { |
| 263 | int i; | ||
| 321 | pthread_mutex_init(&tasklist_mutex, NULL); | 264 | pthread_mutex_init(&tasklist_mutex, NULL); |
| 322 | pthread_cond_init (&tasklist_being_filled, NULL); | 265 | pthread_cond_init (&tasklist_being_filled, NULL); |
| 323 | pthread_mutex_init(&bucket_mutex, NULL); | 266 | for (i=0; i < OT_BUCKET_COUNT; ++i) |
| 324 | pthread_cond_init (&bucket_being_unlocked, NULL); | 267 | pthread_mutex_init(bucket_mutex + i, NULL); |
| 325 | byte_zero( all_torrents, sizeof( all_torrents ) ); | 268 | byte_zero( all_torrents, sizeof( all_torrents ) ); |
| 326 | } | 269 | } |
| 327 | 270 | ||
| 328 | void mutex_deinit( ) { | 271 | void mutex_deinit( ) { |
| 329 | pthread_mutex_destroy(&bucket_mutex); | 272 | int i; |
| 330 | pthread_cond_destroy(&bucket_being_unlocked); | 273 | for (i=0; i < OT_BUCKET_COUNT; ++i) |
| 274 | pthread_mutex_destroy(bucket_mutex + i); | ||
| 331 | pthread_mutex_destroy(&tasklist_mutex); | 275 | pthread_mutex_destroy(&tasklist_mutex); |
| 332 | pthread_cond_destroy(&tasklist_being_filled); | 276 | pthread_cond_destroy(&tasklist_being_filled); |
| 333 | byte_zero( all_torrents, sizeof( all_torrents ) ); | 277 | byte_zero( all_torrents, sizeof( all_torrents ) ); |
