@@ -373,20 +373,34 @@ void acl_fiber_mutex_stats_show(const ACL_FIBER_MUTEX_STATS *stats)
373
373
374
374
/****************************************************************************/
375
375
376
+ #if 1
377
+ #define LOCK (m ) while(pthread_mutex_trylock(&(m)->lock) != 0) {}
378
+ #else
379
+ #define LOCK (m ) do { \
380
+ pthread_mutex_lock(&(m)->lock); \
381
+ } while (0)
382
+ #endif
383
+
384
+ #define UNLOCK (m ) do { \
385
+ pthread_mutex_unlock(&(m)->lock); \
386
+ } while (0)
387
+
388
+ // Just for checking deadlock.
376
389
static void thread_waiter_add (ACL_FIBER_MUTEX * mutex , unsigned long tid )
377
390
{
378
391
THREAD_WAITER * waiter = (THREAD_WAITER * ) mem_malloc (sizeof (THREAD_WAITER ));
379
392
waiter -> tid = tid ;
380
- pthread_mutex_lock ( & mutex -> lock );
393
+ LOCK ( mutex );
381
394
array_append (mutex -> waiting_threads , waiter );
382
- pthread_mutex_unlock ( & mutex -> lock );
395
+ UNLOCK ( mutex );
383
396
}
384
397
398
+ // Just for checking deadlock.
385
399
static void thread_waiter_remove (ACL_FIBER_MUTEX * mutex , unsigned long tid )
386
400
{
387
401
ITER iter ;
388
402
389
- pthread_mutex_lock ( & mutex -> lock );
403
+ LOCK ( mutex );
390
404
foreach (iter , mutex -> waiting_threads ) {
391
405
THREAD_WAITER * waiter = (THREAD_WAITER * ) iter .data ;
392
406
if (waiter -> tid == tid ) {
@@ -395,7 +409,7 @@ static void thread_waiter_remove(ACL_FIBER_MUTEX *mutex, unsigned long tid)
395
409
break ;
396
410
}
397
411
}
398
- pthread_mutex_unlock ( & mutex -> lock );
412
+ UNLOCK ( mutex );
399
413
}
400
414
401
415
static void free_locks_onexit (void )
@@ -427,6 +441,12 @@ ACL_FIBER_MUTEX *acl_fiber_mutex_create(unsigned flags)
427
441
mutex = (ACL_FIBER_MUTEX * ) mem_calloc (1 , sizeof (ACL_FIBER_MUTEX ));
428
442
ring_init (& mutex -> me );
429
443
444
+ if (flags & FIBER_MUTEX_F_LOCK_ONCE ) {
445
+ flags &= ~FIBER_MUTEX_F_LOCK_TRY ;
446
+ } else {
447
+ flags |= FIBER_MUTEX_F_LOCK_TRY ;
448
+ }
449
+
430
450
mutex -> flags = flags ;
431
451
432
452
mutex -> waiters = array_create (5 , ARRAY_F_UNORDER );
@@ -456,21 +476,23 @@ void acl_fiber_mutex_free(ACL_FIBER_MUTEX *mutex)
456
476
457
477
static int fiber_mutex_lock_once (ACL_FIBER_MUTEX * mutex )
458
478
{
459
- int wakeup = 0 , pos ;
479
+ int pos ;
460
480
EVENT * ev ;
461
481
ACL_FIBER * fiber ;
462
482
463
483
while (1 ) {
464
- pthread_mutex_lock ( & mutex -> lock );
484
+ LOCK ( mutex );
465
485
if (pthread_mutex_trylock (& mutex -> thread_lock ) == 0 ) {
466
- pthread_mutex_unlock ( & mutex -> lock );
486
+ UNLOCK ( mutex );
467
487
return 0 ;
468
488
}
469
489
470
490
// For the independent thread, only lock the thread mutex.
471
491
if (!var_hook_sys_api ) {
472
- pthread_mutex_unlock (& mutex -> lock );
473
- thread_waiter_add (mutex , thread_self ());
492
+ UNLOCK (mutex );
493
+ if (mutex -> flags & FIBER_MUTEX_F_CHECK_DEADLOCK ) {
494
+ thread_waiter_add (mutex , thread_self ());
495
+ }
474
496
return pthread_mutex_lock (& mutex -> thread_lock );
475
497
}
476
498
@@ -481,11 +503,11 @@ static int fiber_mutex_lock_once(ACL_FIBER_MUTEX *mutex)
481
503
482
504
if (pthread_mutex_trylock (& mutex -> thread_lock ) == 0 ) {
483
505
array_delete (mutex -> waiters , pos , NULL );
484
- pthread_mutex_unlock ( & mutex -> lock );
506
+ UNLOCK ( mutex );
485
507
return 0 ;
486
508
}
487
509
488
- pthread_mutex_unlock ( & mutex -> lock );
510
+ UNLOCK ( mutex );
489
511
490
512
fiber -> wstatus |= FIBER_WAIT_MUTEX ;
491
513
@@ -495,19 +517,14 @@ static int fiber_mutex_lock_once(ACL_FIBER_MUTEX *mutex)
495
517
WAITER_DEC (ev );
496
518
497
519
fiber -> wstatus &= ~FIBER_WAIT_MUTEX ;
498
-
499
- if (++ wakeup > 5 ) {
500
- wakeup = 0 ;
501
- acl_fiber_delay (100 );
502
- }
503
520
}
504
521
}
505
522
506
523
static int fiber_mutex_lock_try (ACL_FIBER_MUTEX * mutex )
507
524
{
508
- int wakeup = 0 , pos ;
525
+ int pos ;
509
526
EVENT * ev ;
510
- ACL_FIBER * fiber = acl_fiber_running () ;
527
+ ACL_FIBER * fiber ;
511
528
512
529
while (1 ) {
513
530
if (pthread_mutex_trylock (& mutex -> thread_lock ) == 0 ) {
@@ -516,22 +533,25 @@ static int fiber_mutex_lock_try(ACL_FIBER_MUTEX *mutex)
516
533
517
534
// For the independent thread, only lock the thread mutex.
518
535
if (!var_hook_sys_api ) {
519
- thread_waiter_add (mutex , thread_self ());
536
+ if (mutex -> flags & FIBER_MUTEX_F_CHECK_DEADLOCK ) {
537
+ thread_waiter_add (mutex , thread_self ());
538
+ }
520
539
return pthread_mutex_lock (& mutex -> thread_lock );
521
540
}
522
541
542
+ fiber = acl_fiber_running ();
523
543
fiber -> sync = sync_waiter_get ();
524
544
525
- pthread_mutex_lock ( & mutex -> lock );
545
+ LOCK ( mutex );
526
546
pos = array_append (mutex -> waiters , fiber );
527
547
528
548
if (pthread_mutex_trylock (& mutex -> thread_lock ) == 0 ) {
529
549
array_delete (mutex -> waiters , pos , NULL );
530
- pthread_mutex_unlock ( & mutex -> lock );
550
+ UNLOCK ( mutex );
531
551
return 0 ;
532
552
}
533
553
534
- pthread_mutex_unlock ( & mutex -> lock );
554
+ UNLOCK ( mutex );
535
555
536
556
fiber -> wstatus |= FIBER_WAIT_MUTEX ;
537
557
@@ -541,28 +561,24 @@ static int fiber_mutex_lock_try(ACL_FIBER_MUTEX *mutex)
541
561
WAITER_DEC (ev );
542
562
543
563
fiber -> wstatus &= ~FIBER_WAIT_MUTEX ;
544
-
545
- if (++ wakeup > 5 ) {
546
- wakeup = 0 ;
547
- acl_fiber_delay (100 );
548
- }
549
564
}
550
565
}
551
566
552
567
int acl_fiber_mutex_lock (ACL_FIBER_MUTEX * mutex )
553
568
{
554
569
int ret ;
555
570
556
- if (mutex -> flags & FIBER_MUTEX_F_LOCK_TRY ) {
557
- ret = fiber_mutex_lock_try (mutex );
558
- } else {
571
+ if (mutex -> flags & FIBER_MUTEX_F_LOCK_ONCE ) {
559
572
ret = fiber_mutex_lock_once (mutex );
573
+ } else {
574
+ ret = fiber_mutex_lock_try (mutex );
560
575
}
576
+
561
577
if (ret == 0 ) {
562
578
unsigned id = acl_fiber_self (); // 0 will return in no fiber mode.
563
579
long me = id == 0 ? - thread_self () : (long ) id ;
564
580
mutex -> owner = me ;
565
- if (me < 0 ) {
581
+ if (me < 0 && ( mutex -> flags & FIBER_MUTEX_F_CHECK_DEADLOCK ) ) {
566
582
thread_waiter_remove (mutex , thread_self ());
567
583
}
568
584
@@ -588,7 +604,7 @@ int acl_fiber_mutex_unlock(ACL_FIBER_MUTEX *mutex)
588
604
ACL_FIBER * fiber ;
589
605
int ret ;
590
606
591
- pthread_mutex_lock ( & mutex -> lock );
607
+ LOCK ( mutex );
592
608
fiber = (ACL_FIBER * ) array_pop_front (mutex -> waiters );
593
609
594
610
// Just a sanity check!
@@ -605,7 +621,7 @@ int acl_fiber_mutex_unlock(ACL_FIBER_MUTEX *mutex)
605
621
606
622
// Unlock the internal prive lock must behind the public thread_lock,
607
623
// or else the waiter maybe be skipped added in lock waiting process.
608
- pthread_mutex_unlock ( & mutex -> lock );
624
+ UNLOCK ( mutex );
609
625
610
626
if (ret != 0 ) {
611
627
return ret ;
0 commit comments