diff options
author | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-02-18 09:56:23 +0100 |
---|---|---|
committer | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-02-18 09:56:23 +0100 |
commit | 48517ca661895a0c70093e78f165866cb9363206 (patch) | |
tree | a440e16a69b0a85cdb5663ba181a1c3ac2bf0bc5 /src/lanes.c | |
parent | 5f092fe0ec8b6942c63262e7c14c7e4ba913b023 (diff) | |
download | lanes-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/lanes.c')
-rw-r--r-- | src/lanes.c | 41 |
1 files changed, 27 insertions, 14 deletions
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 | ||
55 | char const* VERSION = "3.9.0"; | 55 | char 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 |
2922 | static void init_once_LOCKED( lua_State* L) | 2921 | */ |
2922 | static 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 | ||
3040 | static volatile long s_initCount = 0; | 3042 | static 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 |
3045 | LUAG_FUNC( configure) | 3047 | LUAG_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 |