aboutsummaryrefslogtreecommitdiff
path: root/src/keeper.c
diff options
context:
space:
mode:
authorBenoit Germain <bnt period germain arrobase gmail period com>2014-02-18 09:56:23 +0100
committerBenoit Germain <bnt period germain arrobase gmail period com>2014-02-18 09:56:23 +0100
commit48517ca661895a0c70093e78f165866cb9363206 (patch)
treea440e16a69b0a85cdb5663ba181a1c3ac2bf0bc5 /src/keeper.c
parent5f092fe0ec8b6942c63262e7c14c7e4ba913b023 (diff)
downloadlanes-48517ca661895a0c70093e78f165866cb9363206.tar.gz
lanes-48517ca661895a0c70093e78f165866cb9363206.tar.bz2
lanes-48517ca661895a0c70093e78f165866cb9363206.zip
Lanes init crash fix
* bumped version to 3.9.1 * keeper array is allocated with master state's alloc function instead of malloc()/free() * prevent application crash when specifying a very large number of keepers in the configuration options * removed some keeper desinit legacy dead code * any error occuring during one-time inits is raised outside the one-time mutex protected code region
Diffstat (limited to 'src/keeper.c')
-rw-r--r--src/keeper.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/src/keeper.c b/src/keeper.c
index 9b77c75..0f54e13 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -580,11 +580,7 @@ int keepercall_count( lua_State* L)
580static struct s_Keeper *GKeepers = NULL; 580static struct s_Keeper *GKeepers = NULL;
581static int GNbKeepers = 0; 581static int GNbKeepers = 0;
582 582
583#if HAVE_KEEPER_ATEXIT_DESINIT 583void close_keepers( lua_State* L)
584static void atexit_close_keepers( void)
585#else // HAVE_KEEPER_ATEXIT_DESINIT
586void close_keepers( void)
587#endif // HAVE_KEEPER_ATEXIT_DESINIT
588{ 584{
589 int i; 585 int i;
590 int const nbKeepers = GNbKeepers; 586 int const nbKeepers = GNbKeepers;
@@ -604,25 +600,29 @@ void close_keepers( void)
604 } 600 }
605 if( GKeepers != NULL) 601 if( GKeepers != NULL)
606 { 602 {
607 free( GKeepers); 603 void* allocUD;
604 lua_Alloc allocF = lua_getallocf( L, &allocUD);
605 allocF( allocUD, GKeepers, nbKeepers * sizeof( struct s_Keeper), 0);
608 } 606 }
609 GKeepers = NULL; 607 GKeepers = NULL;
610} 608}
611 609
612/* 610/*
613* Initialize keeper states 611 * Initialize keeper states
614* 612 *
615* If there is a problem, return an error message (NULL for okay). 613 * If there is a problem, return an error message (NULL for okay).
616* 614 *
617* Note: Any problems would be design flaws; the created Lua state is left 615 * Note: Any problems would be design flaws; the created Lua state is left
618* unclosed, because it does not really matter. In production code, this 616 * unclosed, because it does not really matter. In production code, this
619* function never fails. 617 * function never fails.
620* settings table is at position 1 on the stack 618 * settings table is at position 1 on the stack
621*/ 619 * pushes an error string on the stack in case of problem
622char const* init_keepers( lua_State* L) 620 */
621int init_keepers( lua_State* L)
623{ 622{
624 int i; 623 int i;
625 PROPAGATE_ALLOCF_PREP( L); 624 void* allocUD;
625 lua_Alloc allocF = lua_getallocf( L, &allocUD);
626 626
627 STACK_CHECK( L); // L K 627 STACK_CHECK( L); // L K
628 lua_getfield( L, 1, "nb_keepers"); // nb_keepers 628 lua_getfield( L, 1, "nb_keepers"); // nb_keepers
@@ -630,13 +630,21 @@ char const* init_keepers( lua_State* L)
630 lua_pop( L, 1); // 630 lua_pop( L, 1); //
631 assert( GNbKeepers >= 1); 631 assert( GNbKeepers >= 1);
632 632
633 GKeepers = malloc( GNbKeepers * sizeof( struct s_Keeper)); 633 GKeepers = (struct s_Keeper*) allocF( allocUD, NULL, 0, GNbKeepers * sizeof( struct s_Keeper));
634 if( GKeepers == NULL)
635 {
636 lua_pushliteral( L, "init_keepers() failed while creating keeper array; out of memory");
637 STACK_MID( L, 1);
638 return 1;
639 }
634 for( i = 0; i < GNbKeepers; ++ i) 640 for( i = 0; i < GNbKeepers; ++ i)
635 { 641 {
636 lua_State* K = PROPAGATE_ALLOCF_ALLOC(); 642 lua_State* K = PROPAGATE_ALLOCF_ALLOC();
637 if( K == NULL) 643 if( K == NULL)
638 { 644 {
639 (void) luaL_error( L, "init_keepers() failed while creating keeper state; out of memory"); 645 lua_pushliteral( L, "init_keepers() failed while creating keeper states; out of memory");
646 STACK_MID( L, 1);
647 return 1;
640 } 648 }
641 STACK_CHECK( K); 649 STACK_CHECK( K);
642 650
@@ -652,14 +660,26 @@ char const* init_keepers( lua_State* L)
652 lua_getglobal( L, "package"); // package 660 lua_getglobal( L, "package"); // package
653 if( !lua_isnil( L, -1)) 661 if( !lua_isnil( L, -1))
654 { 662 {
655 luaG_inter_copy_package( L, K, -1, eLM_ToKeeper); 663 // when copying with mode eLM_ToKeeper, error message is pushed at the top of the stack, not raised immediately
664 if( luaG_inter_copy_package( L, K, -1, eLM_ToKeeper))
665 {
666 // if something went wrong, the error message is at the top of the stack
667 lua_remove( L, -2); // error_msg
668 STACK_MID( L, 1);
669 return 1;
670 }
656 } 671 }
657 lua_pop( L, 1); // 672 lua_pop( L, 1); //
658 STACK_MID( L, 0); 673 STACK_MID( L, 0);
659 674
660 // attempt to call on_state_create(), if we have one and it is a C function 675 // attempt to call on_state_create(), if we have one and it is a C function
661 // (only support a C function because we can't transfer executable Lua code in keepers) 676 // (only support a C function because we can't transfer executable Lua code in keepers)
662 call_on_state_create( K, L, eLM_ToKeeper); 677 if( call_on_state_create( K, L, eLM_ToKeeper))
678 {
679 // if something went wrong, the error message is at the top of the stack
680 STACK_MID( L, 1); // error_msg
681 return 1;
682 }
663 683
664 // to see VM name in Decoda debugger 684 // to see VM name in Decoda debugger
665 lua_pushliteral( K, "Keeper #"); // "Keeper #" 685 lua_pushliteral( K, "Keeper #"); // "Keeper #"
@@ -678,11 +698,8 @@ char const* init_keepers( lua_State* L)
678 MUTEX_RECURSIVE_INIT( &GKeepers[i].lock_); 698 MUTEX_RECURSIVE_INIT( &GKeepers[i].lock_);
679 GKeepers[i].L = K; 699 GKeepers[i].L = K;
680 } 700 }
681#if HAVE_KEEPER_ATEXIT_DESINIT
682 atexit( atexit_close_keepers);
683#endif // HAVE_KEEPER_ATEXIT_DESINIT
684 STACK_END( L, 0); 701 STACK_END( L, 0);
685 return NULL; // ok 702 return 0; // success
686} 703}
687 704
688struct s_Keeper* keeper_acquire( unsigned long magic_) 705struct s_Keeper* keeper_acquire( unsigned long magic_)