aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <bnt period germain arrobase gmail period com>2013-12-20 11:47:38 +0100
committerBenoit Germain <bnt period germain arrobase gmail period com>2013-12-20 11:47:38 +0100
commit95c696cffe7bf16e27d6d766750c96a38dd23b32 (patch)
treec12099fbff87a330bc0998ec6961c97e03c1c8f2 /src
parent4ece73b1e0d8f75fa63a5b39a91731147870bd0a (diff)
downloadlanes-95c696cffe7bf16e27d6d766750c96a38dd23b32.tar.gz
lanes-95c696cffe7bf16e27d6d766750c96a38dd23b32.tar.bz2
lanes-95c696cffe7bf16e27d6d766750c96a38dd23b32.zip
fixed a shutdown crash
* fixed a crash that can occur at shutdown when an object stored inside a keeper state performs a linda operation on a linda making use of another keeper * bumped version to 3.7.5
Diffstat (limited to 'src')
-rw-r--r--src/keeper.c16
-rw-r--r--src/lanes.c25
2 files changed, 26 insertions, 15 deletions
diff --git a/src/keeper.c b/src/keeper.c
index 99f510b..4c90069 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -184,7 +184,8 @@ static void push_table( lua_State* L, int idx)
184int keeper_push_linda_storage( lua_State* L, void* ptr) 184int keeper_push_linda_storage( lua_State* L, void* ptr)
185{ 185{
186 struct s_Keeper* K = keeper_acquire( ptr); 186 struct s_Keeper* K = keeper_acquire( ptr);
187 lua_State* KL = K->L; 187 lua_State* KL = K ? K->L : NULL;
188 if( KL == NULL) return 0;
188 STACK_CHECK( KL); 189 STACK_CHECK( KL);
189 lua_pushlightuserdata( KL, fifos_key); // fifos_key 190 lua_pushlightuserdata( KL, fifos_key); // fifos_key
190 lua_rawget( KL, LUA_REGISTRYINDEX); // fifos 191 lua_rawget( KL, LUA_REGISTRYINDEX); // fifos
@@ -535,14 +536,18 @@ void close_keepers( void)
535#endif // HAVE_KEEPER_ATEXIT_DESINIT 536#endif // HAVE_KEEPER_ATEXIT_DESINIT
536{ 537{
537 int i; 538 int i;
538 // 2-pass close, in case a keeper holds a reference to a linda bound to another keeoer 539 int const nbKeepers = GNbKeepers;
539 for( i = 0; i < GNbKeepers; ++ i) 540 // NOTE: imagine some keeper state N+1 currently holds a linda that uses another keeper N, and a _gc that will make use of it
541 // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists
542 // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success
543 GNbKeepers = 0;
544 for( i = 0; i < nbKeepers; ++ i)
540 { 545 {
541 lua_State* L = GKeepers[i].L; 546 lua_State* L = GKeepers[i].L;
542 GKeepers[i].L = NULL; 547 GKeepers[i].L = NULL;
543 lua_close( L); 548 lua_close( L);
544 } 549 }
545 for( i = 0; i < GNbKeepers; ++ i) 550 for( i = 0; i < nbKeepers; ++ i)
546 { 551 {
547 MUTEX_FREE( &GKeepers[i].lock_); 552 MUTEX_FREE( &GKeepers[i].lock_);
548 } 553 }
@@ -551,7 +556,6 @@ void close_keepers( void)
551 free( GKeepers); 556 free( GKeepers);
552 } 557 }
553 GKeepers = NULL; 558 GKeepers = NULL;
554 GNbKeepers = 0;
555} 559}
556 560
557/* 561/*
@@ -626,7 +630,7 @@ struct s_Keeper* keeper_acquire( void const* ptr)
626 * have to cast to unsigned long to avoid compilation warnings about loss of data when converting pointer-to-integer 630 * have to cast to unsigned long to avoid compilation warnings about loss of data when converting pointer-to-integer
627 */ 631 */
628 unsigned int i = (unsigned int)(((unsigned long)(ptr) >> 3) % GNbKeepers); 632 unsigned int i = (unsigned int)(((unsigned long)(ptr) >> 3) % GNbKeepers);
629 struct s_Keeper *K= &GKeepers[i]; 633 struct s_Keeper* K= &GKeepers[i];
630 634
631 MUTEX_LOCK( &K->lock_); 635 MUTEX_LOCK( &K->lock_);
632 //++ K->count; 636 //++ K->count;
diff --git a/src/lanes.c b/src/lanes.c
index 6621735..e66342d 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -52,7 +52,7 @@
52 * ... 52 * ...
53 */ 53 */
54 54
55char const* VERSION = "3.7.4"; 55char const* VERSION = "3.7.5";
56 56
57/* 57/*
58=============================================================================== 58===============================================================================
@@ -420,7 +420,8 @@ LUAG_FUNC( linda_send)
420 STACK_GROW(L, 1); 420 STACK_GROW(L, 1);
421 { 421 {
422 struct s_Keeper* K = keeper_acquire( linda); 422 struct s_Keeper* K = keeper_acquire( linda);
423 lua_State* KL = K->L; // need to do this for 'STACK_CHECK' 423 lua_State* KL = K ? K->L : NULL; // need to do this for 'STACK_CHECK'
424 if( KL == NULL) return 0;
424 STACK_CHECK( KL); 425 STACK_CHECK( KL);
425 for( ;;) 426 for( ;;)
426 { 427 {
@@ -584,6 +585,7 @@ LUAG_FUNC( linda_receive)
584 585
585 { 586 {
586 struct s_Keeper *K = keeper_acquire( linda); 587 struct s_Keeper *K = keeper_acquire( linda);
588 if( K == NULL) return 0;
587 for( ;;) 589 for( ;;)
588 { 590 {
589 // all arguments of receive() but the first are passed to the keeper's receive function 591 // all arguments of receive() but the first are passed to the keeper's receive function
@@ -690,6 +692,7 @@ LUAG_FUNC( linda_set)
690 { 692 {
691 int pushed; 693 int pushed;
692 struct s_Keeper *K = keeper_acquire( linda); 694 struct s_Keeper *K = keeper_acquire( linda);
695 if( K == NULL) return 0;
693 // no nil->sentinel toggling, we really clear the linda contents for the given key with a set() 696 // no nil->sentinel toggling, we really clear the linda contents for the given key with a set()
694 pushed = keeper_call( K->L, KEEPER_API( set), L, linda, 2); 697 pushed = keeper_call( K->L, KEEPER_API( set), L, linda, 2);
695 if( pushed >= 0) // no error? 698 if( pushed >= 0) // no error?
@@ -722,7 +725,7 @@ LUAG_FUNC( linda_set)
722 */ 725 */
723LUAG_FUNC( linda_count) 726LUAG_FUNC( linda_count)
724{ 727{
725 struct s_Linda *linda= lua_toLinda( L, 1); 728 struct s_Linda* linda = lua_toLinda( L, 1);
726 int pushed; 729 int pushed;
727 730
728 luaL_argcheck( L, linda, 1, "expected a linda object!"); 731 luaL_argcheck( L, linda, 1, "expected a linda object!");
@@ -730,7 +733,8 @@ LUAG_FUNC( linda_count)
730 check_key_types( L, 2, lua_gettop( L)); 733 check_key_types( L, 2, lua_gettop( L));
731 734
732 { 735 {
733 struct s_Keeper *K = keeper_acquire( linda); 736 struct s_Keeper* K = keeper_acquire( linda);
737 if( K == NULL) return 0;
734 pushed = keeper_call( K->L, KEEPER_API( count), L, linda, 2); 738 pushed = keeper_call( K->L, KEEPER_API( count), L, linda, 2);
735 keeper_release( K); 739 keeper_release( K);
736 if( pushed < 0) 740 if( pushed < 0)
@@ -758,14 +762,15 @@ LUAG_FUNC( linda_get)
758 check_key_types( L, 2, 2); 762 check_key_types( L, 2, 2);
759 763
760 { 764 {
761 struct s_Keeper *K = keeper_acquire( linda); 765 struct s_Keeper* K = keeper_acquire( linda);
766 if( K == NULL) return 0;
762 pushed = keeper_call( K->L, KEEPER_API( get), L, linda, 2); 767 pushed = keeper_call( K->L, KEEPER_API( get), L, linda, 2);
763 ASSERT_L( pushed==0 || pushed==1 ); 768 ASSERT_L( pushed == 0 || pushed == 1);
764 if( pushed > 0) 769 if( pushed > 0)
765 { 770 {
766 keeper_toggle_nil_sentinels( L, lua_gettop( L) - pushed, 0); 771 keeper_toggle_nil_sentinels( L, lua_gettop( L) - pushed, 0);
767 } 772 }
768 keeper_release(K); 773 keeper_release( K);
769 // must trigger error after keeper state has been released 774 // must trigger error after keeper state has been released
770 if( pushed < 0) 775 if( pushed < 0)
771 { 776 {
@@ -784,7 +789,8 @@ LUAG_FUNC( linda_get)
784*/ 789*/
785LUAG_FUNC( linda_limit) 790LUAG_FUNC( linda_limit)
786{ 791{
787 struct s_Linda* linda= lua_toLinda( L, 1 ); 792 struct s_Linda* linda= lua_toLinda( L, 1);
793 int pushed;
788 794
789 luaL_argcheck( L, linda, 1, "expected a linda object!"); 795 luaL_argcheck( L, linda, 1, "expected a linda object!");
790 // make sure we got a key and a limit 796 // make sure we got a key and a limit
@@ -796,7 +802,8 @@ LUAG_FUNC( linda_limit)
796 802
797 { 803 {
798 struct s_Keeper* K = keeper_acquire( linda); 804 struct s_Keeper* K = keeper_acquire( linda);
799 int pushed = keeper_call( K->L, KEEPER_API( limit), L, linda, 2); 805 if( K == NULL) return 0;
806 pushed = keeper_call( K->L, KEEPER_API( limit), L, linda, 2);
800 ASSERT_L( pushed <= 0); // either error or no return values 807 ASSERT_L( pushed <= 0); // either error or no return values
801 keeper_release( K); 808 keeper_release( K);
802 // must trigger error after keeper state has been released 809 // must trigger error after keeper state has been released