Changeset 4045
- Timestamp:
- Dec 3, 2007, 4:26:02 PM (14 years ago)
- Location:
- branches/0.9x/libtransmission
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/0.9x/libtransmission/fdlimit.c
r3917 r4045 110 110 int normalMax; 111 111 tr_lock * lock; 112 tr_cond * cond;113 112 struct tr_openfile open[TR_MAX_OPEN_FILES]; 114 113 }; … … 181 180 o->fd = -1; 182 181 o->isCheckedOut = 0; 183 tr_condSignal( gFd->cond );184 182 } 185 183 … … 193 191 tr_fdFileCheckout( const char * filename, int write ) 194 192 { 195 int i, winner ;193 int i, winner = -1; 196 194 struct tr_openfile * o; 197 195 … … 216 214 if( fileIsCheckedOut( o ) ) { 217 215 dbgmsg( "found it! it's open, but checked out. waiting..." ); 218 tr_condWait( gFd->cond, gFd->lock ); 216 tr_lockUnlock( gFd->lock ); 217 tr_wait( 200 ); 218 tr_lockLock( gFd->lock ); 219 219 i = -1; /* reloop */ 220 220 continue; … … 229 229 dbgmsg( "found it! it's ready for use!" ); 230 230 winner = i; 231 goto done; 232 } 233 231 break; 232 } 234 233 235 234 dbgmsg( "it's not already open. looking for an open slot or an old file." ); 236 for( ;;)235 while( winner < 0 ) 237 236 { 238 237 uint64_t date = tr_date( ) + 1; 239 winner = -1; 240 238 239 /* look for the file that's been open longest */ 241 240 for( i=0; i<TR_MAX_OPEN_FILES; ++i ) 242 241 { … … 246 245 winner = i; 247 246 dbgmsg( "found an empty slot in %d", winner ); 248 goto done;247 break; 249 248 } 250 249 … … 258 257 dbgmsg( "closing file '%s', slot #%d", gFd->open[winner].filename, winner ); 259 258 TrCloseFile( winner ); 260 goto done; 261 } 262 263 /* All used! Wait a bit and try again */ 264 dbgmsg( "everything's full! waiting for someone else to finish something" ); 265 tr_condWait( gFd->cond, gFd->lock ); 266 } 267 268 done: 269 259 } else { 260 dbgmsg( "everything's full! waiting for someone else to finish something" ); 261 tr_lockUnlock( gFd->lock ); 262 tr_wait( 200 ); 263 tr_lockLock( gFd->lock ); 264 } 265 } 266 267 assert( winner >= 0 ); 270 268 o = &gFd->open[winner]; 271 269 if( !fileIsOpen( o ) ) … … 310 308 } 311 309 312 tr_condSignal( gFd->cond );313 310 tr_lockUnlock( gFd->lock ); 314 311 } … … 336 333 } 337 334 338 tr_condSignal( gFd->cond );339 335 tr_lockUnlock( gFd->lock ); 340 336 } … … 463 459 gFd = tr_new0( struct tr_fd_s, 1 ); 464 460 gFd->lock = tr_lockNew( ); 465 gFd->cond = tr_condNew( );466 461 467 462 /* count the max number of sockets we can use */ … … 491 486 492 487 tr_lockFree( gFd->lock ); 493 tr_condFree( gFd->cond );494 488 495 489 tr_list_free( &reservedSockets, NULL ); -
branches/0.9x/libtransmission/platform.c
r3897 r4045 39 39 #include <shlobj.h> /* for CSIDL_APPDATA, CSIDL_PROFILE */ 40 40 #else 41 #define _XOPEN_SOURCE 500 /* needed for recursive locks. */ 42 #ifndef __USE_UNIX98 43 #define __USE_UNIX98 /* some older Linuxes need it spelt out for them */ 44 #endif 41 45 #include <pthread.h> 42 46 #endif … … 190 194 struct tr_lock 191 195 { 192 uint32_t depth;196 int depth; 193 197 #ifdef __BEOS__ 194 198 sem_id lock; … … 211 215 l->lock = create_sem( 1, "" ); 212 216 #elif defined(WIN32) 213 InitializeCriticalSection( &l->lock ); 214 #else 215 pthread_mutex_init( &l->lock, NULL ); 217 InitializeCriticalSection( &l->lock ); /* critical sections support recursion */ 218 #else 219 pthread_mutexattr_t attr; 220 pthread_mutexattr_init( &attr ); 221 pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); 222 pthread_mutex_init( &l->lock, &attr ); 216 223 #endif 217 224 … … 235 242 tr_lockLock( tr_lock * l ) 236 243 { 237 const tr_thread_id currentThread = tr_getCurrentThread( ); 238 239 if( l->lockThread == currentThread ) 240 { 241 ++l->depth; 242 } 243 else 244 { 245 #ifdef __BEOS__ 246 acquire_sem( l->lock ); 247 #elif defined(WIN32) 248 EnterCriticalSection( &l->lock ); 249 #else 250 pthread_mutex_lock( &l->lock ); 251 #endif 252 l->lockThread = currentThread; 253 l->depth = 1; 254 } 244 #ifdef __BEOS__ 245 acquire_sem( l->lock ); 246 #elif defined(WIN32) 247 EnterCriticalSection( &l->lock ); 248 #else 249 pthread_mutex_lock( &l->lock ); 250 #endif 251 assert( l->depth >= 0 ); 252 if( l->depth ) 253 assert( tr_areThreadsEqual( l->lockThread, tr_getCurrentThread() ) ); 254 l->lockThread = tr_getCurrentThread( ); 255 ++l->depth; 255 256 } 256 257 … … 259 260 { 260 261 return ( l->depth > 0 ) 261 && ( l->lockThread == tr_getCurrentThread() );262 && ( tr_areThreadsEqual( l->lockThread, tr_getCurrentThread() ) ); 262 263 } 263 264 … … 265 266 tr_lockUnlock( tr_lock * l ) 266 267 { 267 assert( tr_lockHave( l ) ); 268 269 if( !--l->depth ) 270 { 271 l->lockThread = 0; 272 #ifdef __BEOS__ 273 release_sem( l->lock ); 274 #elif defined(WIN32) 275 LeaveCriticalSection( &l->lock ); 276 #else 277 pthread_mutex_unlock( &l->lock ); 278 #endif 279 } 280 } 281 282 /*** 283 **** COND 284 ***/ 285 286 struct tr_cond 287 { 288 #ifdef __BEOS__ 289 sem_id sem; 290 thread_id threads[BEOS_MAX_THREADS]; 291 int start, end; 292 #elif defined(WIN32) 293 tr_list * events; 294 tr_lock * lock; 295 #else 296 pthread_cond_t cond; 297 #endif 298 }; 299 300 #ifdef WIN32 301 static DWORD getContEventTLS( void ) 302 { 303 static int inited = FALSE; 304 static DWORD event_tls; 305 if( !inited ) { 306 inited = TRUE; 307 event_tls = TlsAlloc(); 308 } 309 return event_tls; 310 } 311 #endif 312 313 tr_cond* 314 tr_condNew( void ) 315 { 316 tr_cond * c = tr_new0( tr_cond, 1 ); 317 #ifdef __BEOS__ 318 c->sem = create_sem( 1, "" ); 319 c->start = 0; 320 c->end = 0; 321 #elif defined(WIN32) 322 c->events = NULL; 323 c->lock = tr_lockNew( ); 324 #else 325 pthread_cond_init( &c->cond, NULL ); 326 #endif 327 return c; 328 } 329 330 void 331 tr_condWait( tr_cond * c, tr_lock * l ) 332 { 333 #ifdef __BEOS__ 334 335 /* Keep track of that thread */ 336 acquire_sem( c->sem ); 337 c->threads[c->end] = find_thread( NULL ); 338 c->end = ( c->end + 1 ) % BEOS_MAX_THREADS; 339 assert( c->end != c->start ); /* We hit BEOS_MAX_THREADS, arggh */ 340 release_sem( c->sem ); 341 268 assert( l->depth > 0 ); 269 assert( tr_areThreadsEqual( l->lockThread, tr_getCurrentThread() )); 270 271 --l->depth; 272 assert( l->depth >= 0 ); 273 #ifdef __BEOS__ 342 274 release_sem( l->lock ); 343 suspend_thread( find_thread( NULL ) ); /* Wait for signal */ 344 acquire_sem( l->lock ); 345 346 #elif defined(WIN32) 347 348 /* get this thread's cond event */ 349 DWORD key = getContEventTLS ( ); 350 HANDLE hEvent = TlsGetValue( key ); 351 if( !hEvent ) { 352 hEvent = CreateEvent( 0, FALSE, FALSE, 0 ); 353 TlsSetValue( key, hEvent ); 354 } 355 356 /* add it to the list of events waiting to be signaled */ 357 tr_lockLock( c->lock ); 358 tr_list_append( &c->events, hEvent ); 359 tr_lockUnlock( c->lock ); 360 361 /* now wait for it to be signaled */ 362 tr_lockUnlock( l ); 363 WaitForSingleObject( hEvent, INFINITE ); 364 tr_lockLock( l ); 365 366 /* remove it from the list of events waiting to be signaled */ 367 tr_lockLock( c->lock ); 368 tr_list_remove_data( &c->events, hEvent ); 369 tr_lockUnlock( c->lock ); 370 371 #else 372 373 pthread_cond_wait( &c->cond, &l->lock ); 374 375 #endif 376 } 377 378 #ifdef __BEOS__ 379 static int condTrySignal( tr_cond * c ) 380 { 381 if( c->start == c->end ) 382 return 1; 383 384 for( ;; ) 385 { 386 thread_info info; 387 get_thread_info( c->threads[c->start], &info ); 388 if( info.state == B_THREAD_SUSPENDED ) 389 { 390 resume_thread( c->threads[c->start] ); 391 c->start = ( c->start + 1 ) % BEOS_MAX_THREADS; 392 break; 393 } 394 /* The thread is not suspended yet, which can happen since 395 * tr_condWait does not atomically suspends after releasing 396 * the semaphore. Wait a bit and try again. */ 397 snooze( 5000 ); 398 } 399 return 0; 400 } 401 #endif 402 void 403 tr_condSignal( tr_cond * c ) 404 { 405 #ifdef __BEOS__ 406 407 acquire_sem( c->sem ); 408 condTrySignal( c ); 409 release_sem( c->sem ); 410 411 #elif defined(WIN32) 412 413 tr_lockLock( c->lock ); 414 if( c->events != NULL ) 415 SetEvent( (HANDLE)c->events->data ); 416 tr_lockUnlock( c->lock ); 417 418 #else 419 420 pthread_cond_signal( &c->cond ); 421 422 #endif 423 } 424 425 void 426 tr_condBroadcast( tr_cond * c ) 427 { 428 #ifdef __BEOS__ 429 430 acquire_sem( c->sem ); 431 while( !condTrySignal( c ) ); 432 release_sem( c->sem ); 433 434 #elif defined(WIN32) 435 436 tr_list * l; 437 tr_lockLock( c->lock ); 438 for( l=c->events; l!=NULL; l=l->next ) 439 SetEvent( (HANDLE)l->data ); 440 tr_lockUnlock( c->lock ); 441 442 #else 443 444 pthread_cond_broadcast( &c->cond ); 445 446 #endif 447 } 448 449 void 450 tr_condFree( tr_cond * c ) 451 { 452 #ifdef __BEOS__ 453 delete_sem( c->sem ); 454 #elif defined(WIN32) 455 tr_list_free( &c->events, NULL ); 456 tr_lockFree( c->lock ); 457 #else 458 pthread_cond_destroy( &c->cond ); 459 #endif 460 tr_free( c ); 461 } 462 275 #elif defined(WIN32) 276 LeaveCriticalSection( &l->lock ); 277 #else 278 pthread_mutex_unlock( &l->lock ); 279 #endif 280 } 463 281 464 282 /*** … … 852 670 } 853 671 854 bzero( &snl, sizeof( snl) );672 memset( &snl, 0, sizeof(snl) ); 855 673 snl.nl_family = AF_NETLINK; 856 674 857 bzero( &req, sizeof( req) );675 memset( &req, 0, sizeof(req) ); 858 676 req.nlh.nlmsg_len = NLMSG_LENGTH( sizeof( req.rtg ) ); 859 677 req.nlh.nlmsg_type = RTM_GETROUTE; … … 893 711 for( ;; ) 894 712 { 895 bzero( &snl, sizeof( snl ) );896 713 slen = sizeof( snl ); 714 memset( &snl, 0, slen ); 897 715 res = recvfrom( fd, buf, len, 0, (struct sockaddr *) &snl, &slen ); 898 716 if( 0 > res ) -
branches/0.9x/libtransmission/platform.h
r3897 r4045 26 26 27 27 typedef struct tr_lock tr_lock; 28 typedef struct tr_cond tr_cond;29 28 typedef struct tr_thread tr_thread; 30 29 … … 43 42 int tr_lockHave ( const tr_lock * ); 44 43 45 tr_cond * tr_condNew ( void );46 void tr_condFree ( tr_cond * );47 void tr_condSignal ( tr_cond * );48 void tr_condBroadcast ( tr_cond * );49 void tr_condWait ( tr_cond *, tr_lock * );50 51 44 struct in_addr; /* forward declaration to calm gcc down */ 52 45 int
Note: See TracChangeset
for help on using the changeset viewer.