diff options
author | Benoit Germain <bnt period germain arrobase gmail period com> | 2013-12-20 11:47:38 +0100 |
---|---|---|
committer | Benoit Germain <bnt period germain arrobase gmail period com> | 2013-12-20 11:47:38 +0100 |
commit | 95c696cffe7bf16e27d6d766750c96a38dd23b32 (patch) | |
tree | c12099fbff87a330bc0998ec6961c97e03c1c8f2 /src/keeper.c | |
parent | 4ece73b1e0d8f75fa63a5b39a91731147870bd0a (diff) | |
download | lanes-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/keeper.c')
-rw-r--r-- | src/keeper.c | 16 |
1 files changed, 10 insertions, 6 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) | |||
184 | int keeper_push_linda_storage( lua_State* L, void* ptr) | 184 | int 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; |