aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES7
-rw-r--r--src/keeper.c67
-rw-r--r--src/keeper.h11
-rw-r--r--src/lanes.c41
-rw-r--r--src/tools.c33
-rw-r--r--src/tools.h4
6 files changed, 102 insertions, 61 deletions
diff --git a/CHANGES b/CHANGES
index e7a08f7..4a1ce49 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,12 @@
1CHANGES: 1CHANGES:
2 2
3CHANGE 101: BGe 18-Feb-14
4 * version 3.9.1
5 * removed some keeper desinit legacy dead code
6 * keeper array is allocated with master state's alloc function instead of malloc()/free()
7 * prevent application crash when specifying a very large number of keepers in the configuration options
8 * any error occuring during one-time inits is raised outside the one-time mutex protected code region
9
3CHANGE 100: BGe 17-Feb-14 10CHANGE 100: BGe 17-Feb-14
4 * lanes.linda() accepts an optional integer group to give control on keeper state repartition 11 * lanes.linda() accepts an optional integer group to give control on keeper state repartition
5 12
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_)
diff --git a/src/keeper.h b/src/keeper.h
index ed11ec4..5a52f3b 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -8,15 +8,8 @@ struct s_Keeper
8 //int count; 8 //int count;
9}; 9};
10 10
11// if enabled, call close_keepers at the very last as we want to be sure no thread is GCing after. 11int init_keepers( lua_State* L);
12// (and therefore may perform linda object dereferencing after keepers are gone) 12void close_keepers( lua_State* L);
13// problem: maybe on some platforms (linux) atexit() is called after DLL/so are unloaded...
14#define HAVE_KEEPER_ATEXIT_DESINIT 0
15
16char const* init_keepers( lua_State* L);
17#if !HAVE_KEEPER_ATEXIT_DESINIT
18void close_keepers( void);
19#endif // HAVE_KEEPER_ATEXIT_DESINIT
20 13
21struct s_Keeper *keeper_acquire( unsigned long magic_); 14struct s_Keeper *keeper_acquire( unsigned long magic_);
22#define KEEPER_MAGIC_SHIFT 3 15#define KEEPER_MAGIC_SHIFT 3
diff --git a/src/lanes.c b/src/lanes.c
index 71a9000..76722fe 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -52,7 +52,7 @@
52 * ... 52 * ...
53 */ 53 */
54 54
55char const* VERSION = "3.9.0"; 55char const* VERSION = "3.9.1";
56 56
57/* 57/*
58=============================================================================== 58===============================================================================
@@ -1679,9 +1679,7 @@ static int selfdestruct_gc( lua_State* L)
1679 DEBUGSPEW_CODE( fprintf( stderr, "Killed %d lane(s) at process end.\n", n)); 1679 DEBUGSPEW_CODE( fprintf( stderr, "Killed %d lane(s) at process end.\n", n));
1680 } 1680 }
1681 } 1681 }
1682#if !HAVE_KEEPER_ATEXIT_DESINIT 1682 close_keepers( L);
1683 close_keepers();
1684#endif // !HAVE_KEEPER_ATEXIT_DESINIT
1685 1683
1686 // remove the protected allocator, if any 1684 // remove the protected allocator, if any
1687 { 1685 {
@@ -2186,7 +2184,8 @@ LUAG_FUNC( thread_new)
2186 // package 2184 // package
2187 if( package != 0) 2185 if( package != 0)
2188 { 2186 {
2189 luaG_inter_copy_package( L, L2, package, eLM_LaneBody); 2187 // when copying with mode eLM_LaneBody, should raise an error in case of problem, not leave it one the stack
2188 (void) luaG_inter_copy_package( L, L2, package, eLM_LaneBody);
2190 } 2189 }
2191 2190
2192 // modules to require in the target lane *before* the function is transfered! 2191 // modules to require in the target lane *before* the function is transfered!
@@ -2916,10 +2915,11 @@ static const struct luaL_Reg lanes_functions [] = {
2916 2915
2917 2916
2918/* 2917/*
2919** One-time initializations 2918 * One-time initializations
2920 * settings table it at position 1 on the stack 2919 * settings table it at position 1 on the stack
2921*/ 2920 * pushes an error string on the stack in case of problem
2922static void init_once_LOCKED( lua_State* L) 2921 */
2922static int init_once_LOCKED( lua_State* L)
2923{ 2923{
2924 initialize_on_state_create( L); 2924 initialize_on_state_create( L);
2925 2925
@@ -2988,10 +2988,11 @@ static void init_once_LOCKED( lua_State* L)
2988#endif // LINUX_SCHED_RR 2988#endif // LINUX_SCHED_RR
2989#endif // PLATFORM_LINUX 2989#endif // PLATFORM_LINUX
2990 { 2990 {
2991 char const* err = init_keepers( L); 2991 // returns non-0 if an error message was pushed on the stack
2992 if (err) 2992 int pushed_error = init_keepers( L);
2993 if( pushed_error)
2993 { 2994 {
2994 (void) luaL_error( L, "Unable to initialize: %s", err ); 2995 return pushed_error;
2995 } 2996 }
2996 } 2997 }
2997 2998
@@ -3030,11 +3031,12 @@ static void init_once_LOCKED( lua_State* L)
3030 lua_insert( L, -2); // Swap key with the Linda object 3031 lua_insert( L, -2); // Swap key with the Linda object
3031 lua_rawset( L, LUA_REGISTRYINDEX); 3032 lua_rawset( L, LUA_REGISTRYINDEX);
3032 3033
3033 // we'll need this everytime we transfer some C function from/to this state 3034 // we'll need this every time we transfer some C function from/to this state
3034 lua_newtable( L); 3035 lua_newtable( L);
3035 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); 3036 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY);
3036 3037
3037 STACK_END( L, 0); 3038 STACK_END( L, 0);
3039 return 0;
3038} 3040}
3039 3041
3040static volatile long s_initCount = 0; 3042static volatile long s_initCount = 0;
@@ -3044,6 +3046,8 @@ static volatile long s_initCount = 0;
3044// param 1: settings table 3046// param 1: settings table
3045LUAG_FUNC( configure) 3047LUAG_FUNC( configure)
3046{ 3048{
3049 // set to 1 if an error occured inside init_once_LOCKED(), and message is found at the top of the stack
3050 int init_once_error = 0;
3047 char const* name = luaL_checkstring( L, lua_upvalueindex( 1)); 3051 char const* name = luaL_checkstring( L, lua_upvalueindex( 1));
3048 _ASSERT_L( L, lua_type( L, 1) == LUA_TTABLE); 3052 _ASSERT_L( L, lua_type( L, 1) == LUA_TTABLE);
3049 STACK_CHECK( L); 3053 STACK_CHECK( L);
@@ -3081,7 +3085,7 @@ LUAG_FUNC( configure)
3081 static volatile int /*bool*/ go_ahead; // = 0 3085 static volatile int /*bool*/ go_ahead; // = 0
3082 if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0) 3086 if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0)
3083 { 3087 {
3084 init_once_LOCKED( L); 3088 init_once_error = init_once_LOCKED( L);
3085 go_ahead = 1; // let others pass 3089 go_ahead = 1; // let others pass
3086 } 3090 }
3087 else 3091 else
@@ -3099,7 +3103,7 @@ LUAG_FUNC( configure)
3099 // 3103 //
3100 if( s_initCount == 0) 3104 if( s_initCount == 0)
3101 { 3105 {
3102 init_once_LOCKED( L); 3106 init_once_error = init_once_LOCKED( L);
3103 s_initCount = 1; 3107 s_initCount = 1;
3104 } 3108 }
3105 } 3109 }
@@ -3107,6 +3111,15 @@ LUAG_FUNC( configure)
3107 } 3111 }
3108#endif // THREADAPI == THREADAPI_PTHREAD 3112#endif // THREADAPI == THREADAPI_PTHREAD
3109 3113
3114 // raise error outside the init-once mutex
3115 if( init_once_error)
3116 {
3117 // will raise an error if the error is not a string (should not happen)
3118 char const* error = luaL_checkstring( L, -1);
3119 // raises an error with the message found at the top of the stack
3120 lua_error( L);
3121 }
3122
3110 // Retrieve main module interface table 3123 // Retrieve main module interface table
3111 lua_pushvalue( L, lua_upvalueindex( 2)); // settings M 3124 lua_pushvalue( L, lua_upvalueindex( 2)); // settings M
3112 // remove configure() (this function) from the module interface 3125 // remove configure() (this function) from the module interface
diff --git a/src/tools.c b/src/tools.c
index 2aa9b82..d149f9b 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -591,7 +591,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
591 DEBUGSPEW_CODE( -- debugspew_indent_depth); 591 DEBUGSPEW_CODE( -- debugspew_indent_depth);
592} 592}
593 593
594void call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode_) 594int call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode_)
595{ 595{
596 if( s_on_state_create_func != NULL) 596 if( s_on_state_create_func != NULL)
597 { 597 {
@@ -607,7 +607,8 @@ void call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode
607 if( mode_ != eLM_LaneBody) 607 if( mode_ != eLM_LaneBody)
608 { 608 {
609 // if attempting to call in a keeper state, do nothing because the function doesn't exist there 609 // if attempting to call in a keeper state, do nothing because the function doesn't exist there
610 return; 610 // this doesn't count as an error though
611 return 0;
611 } 612 }
612 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); 613 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY);
613 lua_getfield( L, -1, "on_state_create"); 614 lua_getfield( L, -1, "on_state_create");
@@ -616,10 +617,12 @@ void call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode
616 // capture error and forward it to main state 617 // capture error and forward it to main state
617 if( lua_pcall( L, 0, 0, 0) != LUA_OK) 618 if( lua_pcall( L, 0, 0, 0) != LUA_OK)
618 { 619 {
619 (void) luaL_error( from_, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1))); 620 lua_pushfstring( from_, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1)));
621 return 1;
620 } 622 }
621 STACK_END( L, 0); 623 STACK_END( L, 0);
622 } 624 }
625 return 0;
623} 626}
624 627
625/* 628/*
@@ -637,7 +640,7 @@ void call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode
637 */ 640 */
638lua_State* luaG_newstate( lua_State* from_, char const* libs_) 641lua_State* luaG_newstate( lua_State* from_, char const* libs_)
639{ 642{
640 // reuse alloc function from the originating state 643 // re-use alloc function from the originating state
641#if PROPAGATE_ALLOCF 644#if PROPAGATE_ALLOCF
642 PROPAGATE_ALLOCF_PREP( from_); 645 PROPAGATE_ALLOCF_PREP( from_);
643#endif // PROPAGATE_ALLOCF 646#endif // PROPAGATE_ALLOCF
@@ -648,7 +651,7 @@ lua_State* luaG_newstate( lua_State* from_, char const* libs_)
648 (void) luaL_error( from_, "luaG_newstate() failed while creating state; out of memory"); 651 (void) luaL_error( from_, "luaG_newstate() failed while creating state; out of memory");
649 } 652 }
650 653
651 // we'll need this everytime we transfer some C function from/to this state 654 // we'll need this every time we transfer some C function from/to this state
652 lua_newtable( L); 655 lua_newtable( L);
653 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); 656 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY);
654 657
@@ -720,7 +723,11 @@ lua_State* luaG_newstate( lua_State* from_, char const* libs_)
720 lua_gc( L, LUA_GCRESTART, 0); 723 lua_gc( L, LUA_GCRESTART, 0);
721 724
722 // call this after the base libraries are loaded and GC is restarted 725 // call this after the base libraries are loaded and GC is restarted
723 call_on_state_create( L, from_, eLM_LaneBody); 726 if( call_on_state_create( L, from_, eLM_LaneBody))
727 {
728 // if something went wrong, the error message is pushed on the stack
729 lua_error( from_);
730 }
724 731
725 STACK_CHECK( L); 732 STACK_CHECK( L);
726 // after all this, register everything we find in our name<->function database 733 // after all this, register everything we find in our name<->function database
@@ -2158,17 +2165,20 @@ int luaG_inter_move( lua_State* L, lua_State* L2, uint_t n, enum eLookupMode mod
2158 return ret; 2165 return ret;
2159} 2166}
2160 2167
2161void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx, enum eLookupMode mode_) 2168int luaG_inter_copy_package( lua_State* L, lua_State* L2, int package_idx_, enum eLookupMode mode_)
2162{ 2169{
2163 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END)); 2170 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END));
2164 DEBUGSPEW_CODE( ++ debugspew_indent_depth); 2171 DEBUGSPEW_CODE( ++ debugspew_indent_depth);
2165 // package 2172 // package
2166 STACK_CHECK( L); 2173 STACK_CHECK( L);
2167 STACK_CHECK( L2); 2174 STACK_CHECK( L2);
2168 _idx = lua_absindex( L, _idx); 2175 package_idx_ = lua_absindex( L, package_idx_);
2169 if( lua_type( L, _idx) != LUA_TTABLE) 2176 if( lua_type( L, package_idx_) != LUA_TTABLE)
2170 { 2177 {
2171 (void) luaL_error( L, "expected package as table, got %s", luaL_typename( L, _idx)); 2178 lua_pushfstring( L, "expected package as table, got %s", luaL_typename( L, package_idx_));
2179 STACK_MID( L, 1);
2180 // raise the error when copying from lane to lane, else just leave it on the stack to be raised later
2181 return ( mode_ == eLM_LaneBody) ? lua_error( L) : 1;
2172 } 2182 }
2173 lua_getglobal( L2, "package"); 2183 lua_getglobal( L2, "package");
2174 if( !lua_isnil( L2, -1)) // package library not loaded: do nothing 2184 if( !lua_isnil( L2, -1)) // package library not loaded: do nothing
@@ -2182,7 +2192,7 @@ void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx, enum eLooku
2182 for( i = 0; entries[i]; ++ i) 2192 for( i = 0; entries[i]; ++ i)
2183 { 2193 {
2184 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s\n" INDENT_END, entries[i])); 2194 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s\n" INDENT_END, entries[i]));
2185 lua_getfield( L, _idx, entries[i]); 2195 lua_getfield( L, package_idx_, entries[i]);
2186 if( lua_isnil( L, -1)) 2196 if( lua_isnil( L, -1))
2187 { 2197 {
2188 lua_pop( L, 1); 2198 lua_pop( L, 1);
@@ -2204,6 +2214,7 @@ void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx, enum eLooku
2204 STACK_END( L2, 0); 2214 STACK_END( L2, 0);
2205 STACK_END( L, 0); 2215 STACK_END( L, 0);
2206 DEBUGSPEW_CODE( -- debugspew_indent_depth); 2216 DEBUGSPEW_CODE( -- debugspew_indent_depth);
2217 return 0;
2207} 2218}
2208 2219
2209 2220
diff --git a/src/tools.h b/src/tools.h
index ebe407b..5bd4b69 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -118,7 +118,7 @@ enum eLookupMode
118}; 118};
119 119
120char const* push_deep_proxy( lua_State* L, DEEP_PRELUDE* prelude, enum eLookupMode mode_); 120char const* push_deep_proxy( lua_State* L, DEEP_PRELUDE* prelude, enum eLookupMode mode_);
121void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx, enum eLookupMode mode_); 121int luaG_inter_copy_package( lua_State* L, lua_State* L2, int package_idx_, enum eLookupMode mode_);
122 122
123int luaG_inter_copy( lua_State *L, lua_State *L2, uint_t n, enum eLookupMode mode_); 123int luaG_inter_copy( lua_State *L, lua_State *L2, uint_t n, enum eLookupMode mode_);
124int luaG_inter_move( lua_State *L, lua_State *L2, uint_t n, enum eLookupMode mode_); 124int luaG_inter_move( lua_State *L, lua_State *L2, uint_t n, enum eLookupMode mode_);
@@ -134,7 +134,7 @@ extern MUTEX_T mtid_lock;
134void populate_func_lookup_table( lua_State* L, int _i, char const* _name); 134void populate_func_lookup_table( lua_State* L, int _i, char const* _name);
135void serialize_require( lua_State *L); 135void serialize_require( lua_State *L);
136int initialize_on_state_create( lua_State *L); 136int initialize_on_state_create( lua_State *L);
137void call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode_); 137int call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode_);
138 138
139extern MUTEX_T require_cs; 139extern MUTEX_T require_cs;
140 140