diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2012-12-14 15:35:26 +0100 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2012-12-14 15:35:26 +0100 |
commit | 11b19bf4d7dfc883e18ea579d978c620865d843f (patch) | |
tree | 602da3de630e4b247b4463c26a846683cad4d074 /src/lanes.c | |
parent | 5107a671f9b47f1576412f4898457edf98384acd (diff) | |
download | lanes-11b19bf4d7dfc883e18ea579d978c620865d843f.tar.gz lanes-11b19bf4d7dfc883e18ea579d978c620865d843f.tar.bz2 lanes-11b19bf4d7dfc883e18ea579d978c620865d843f.zip |
lanes.threads(): core implementation
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 143 |
1 files changed, 112 insertions, 31 deletions
diff --git a/src/lanes.c b/src/lanes.c index 6789e4e..161de59 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -103,6 +103,11 @@ THE SOFTWARE. | |||
103 | # include <sys/types.h> | 103 | # include <sys/types.h> |
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | /* | ||
107 | * Do we want to activate full lane tracking feature? (EXPERIMENTAL) | ||
108 | */ | ||
109 | #define HAVE_LANE_TRACKING 1 | ||
110 | |||
106 | /* Do you want full call stacks, or just the line where the error happened? | 111 | /* Do you want full call stacks, or just the line where the error happened? |
107 | * | 112 | * |
108 | * TBD: The full stack feature does not seem to work (try 'make error'). | 113 | * TBD: The full stack feature does not seem to work (try 'make error'). |
@@ -118,7 +123,9 @@ struct s_lane { | |||
118 | // M: sub-thread OS thread | 123 | // M: sub-thread OS thread |
119 | // S: not used | 124 | // S: not used |
120 | 125 | ||
121 | lua_State *L; | 126 | char const* debug_name; |
127 | |||
128 | lua_State* L; | ||
122 | // | 129 | // |
123 | // M: prepares the state, and reads results | 130 | // M: prepares the state, and reads results |
124 | // S: while S is running, M must keep out of modifying the state | 131 | // S: while S is running, M must keep out of modifying the state |
@@ -164,8 +171,8 @@ struct s_lane { | |||
164 | // S: cleans up after itself if non-NULL at lane exit | 171 | // S: cleans up after itself if non-NULL at lane exit |
165 | }; | 172 | }; |
166 | 173 | ||
167 | static bool_t cancel_test( lua_State *L ); | 174 | static bool_t cancel_test( lua_State*L ); |
168 | static void cancel_error( lua_State *L ); | 175 | static void cancel_error( lua_State*L ); |
169 | 176 | ||
170 | #define CANCEL_TEST_KEY ((void*)cancel_test) // used as registry key | 177 | #define CANCEL_TEST_KEY ((void*)cancel_test) // used as registry key |
171 | #define CANCEL_ERROR ((void*)cancel_error) // 'cancel_error' sentinel | 178 | #define CANCEL_ERROR ((void*)cancel_error) // 'cancel_error' sentinel |
@@ -204,7 +211,7 @@ struct s_Linda; | |||
204 | * Returns: TRUE if a table was pushed | 211 | * Returns: TRUE if a table was pushed |
205 | * FALSE if no table found, not created, and nothing pushed | 212 | * FALSE if no table found, not created, and nothing pushed |
206 | */ | 213 | */ |
207 | static bool_t push_registry_table( lua_State *L, void *key, bool_t create ) { | 214 | static bool_t push_registry_table( lua_State*L, void *key, bool_t create ) { |
208 | 215 | ||
209 | STACK_GROW(L,3); | 216 | STACK_GROW(L,3); |
210 | 217 | ||
@@ -247,7 +254,7 @@ static void linda_id( lua_State*, char const * const which); | |||
247 | #define lua_toLinda(L,n) ((struct s_Linda *)luaG_todeep( L, linda_id, n )) | 254 | #define lua_toLinda(L,n) ((struct s_Linda *)luaG_todeep( L, linda_id, n )) |
248 | 255 | ||
249 | 256 | ||
250 | static void check_key_types( lua_State *L, int _start, int _end) | 257 | static void check_key_types( lua_State*L, int _start, int _end) |
251 | { | 258 | { |
252 | int i; | 259 | int i; |
253 | for( i = _start; i <= _end; ++ i) | 260 | for( i = _start; i <= _end; ++ i) |
@@ -305,7 +312,7 @@ LUAG_FUNC( linda_send) | |||
305 | STACK_GROW(L, 1); | 312 | STACK_GROW(L, 1); |
306 | { | 313 | { |
307 | struct s_Keeper *K = keeper_acquire( linda); | 314 | struct s_Keeper *K = keeper_acquire( linda); |
308 | lua_State *KL = K->L; // need to do this for 'STACK_CHECK' | 315 | lua_State*KL = K->L; // need to do this for 'STACK_CHECK' |
309 | STACK_CHECK( KL) | 316 | STACK_CHECK( KL) |
310 | for( ;;) | 317 | for( ;;) |
311 | { | 318 | { |
@@ -720,8 +727,6 @@ LUAG_FUNC( linda_deep ) { | |||
720 | 727 | ||
721 | static int linda_tostring( lua_State* L, int _idx, bool_t _opt) | 728 | static int linda_tostring( lua_State* L, int _idx, bool_t _opt) |
722 | { | 729 | { |
723 | char text[32]; | ||
724 | int len; | ||
725 | struct s_Linda* linda = lua_toLinda( L, _idx); | 730 | struct s_Linda* linda = lua_toLinda( L, _idx); |
726 | if( !_opt) | 731 | if( !_opt) |
727 | { | 732 | { |
@@ -729,6 +734,8 @@ static int linda_tostring( lua_State* L, int _idx, bool_t _opt) | |||
729 | } | 734 | } |
730 | if( linda) | 735 | if( linda) |
731 | { | 736 | { |
737 | char text[32]; | ||
738 | int len; | ||
732 | if( linda->name[0]) | 739 | if( linda->name[0]) |
733 | len = sprintf( text, "Linda: %.*s", (int)sizeof(text) - 8, linda->name); | 740 | len = sprintf( text, "Linda: %.*s", (int)sizeof(text) - 8, linda->name); |
734 | else | 741 | else |
@@ -808,7 +815,7 @@ LUAG_FUNC( linda_dump) | |||
808 | * For any other strings, the ID function must not react at all. This allows | 815 | * For any other strings, the ID function must not react at all. This allows |
809 | * future extensions of the system. | 816 | * future extensions of the system. |
810 | */ | 817 | */ |
811 | static void linda_id( lua_State *L, char const * const which) | 818 | static void linda_id( lua_State*L, char const * const which) |
812 | { | 819 | { |
813 | if (strcmp( which, "new" )==0) | 820 | if (strcmp( which, "new" )==0) |
814 | { | 821 | { |
@@ -981,7 +988,7 @@ LUAG_FUNC( set_finalizer ) | |||
981 | // | 988 | // |
982 | // TBD: should we add stack trace on failing finalizer, wouldn't be hard.. | 989 | // TBD: should we add stack trace on failing finalizer, wouldn't be hard.. |
983 | // | 990 | // |
984 | static int run_finalizers( lua_State *L, int lua_rc ) | 991 | static int run_finalizers( lua_State*L, int lua_rc ) |
985 | { | 992 | { |
986 | unsigned error_index, tbl_index; | 993 | unsigned error_index, tbl_index; |
987 | unsigned n; | 994 | unsigned n; |
@@ -1176,7 +1183,7 @@ volatile DEEP_PRELUDE *timer_deep; // = NULL | |||
1176 | /* | 1183 | /* |
1177 | * Process end; cancel any still free-running threads | 1184 | * Process end; cancel any still free-running threads |
1178 | */ | 1185 | */ |
1179 | static int selfdestruct_gc( lua_State *L) | 1186 | static int selfdestruct_gc( lua_State*L) |
1180 | { | 1187 | { |
1181 | (void)L; // unused | 1188 | (void)L; // unused |
1182 | if (selfdestruct_first == SELFDESTRUCT_END) return 0; // no free-running threads | 1189 | if (selfdestruct_first == SELFDESTRUCT_END) return 0; // no free-running threads |
@@ -1341,7 +1348,7 @@ static int selfdestruct_gc( lua_State *L) | |||
1341 | * Returns TRUE if any locks are to be exited, and 'cancel_error()' called, | 1348 | * Returns TRUE if any locks are to be exited, and 'cancel_error()' called, |
1342 | * to make execution of the lane end. | 1349 | * to make execution of the lane end. |
1343 | */ | 1350 | */ |
1344 | static bool_t cancel_test( lua_State *L ) { | 1351 | static bool_t cancel_test( lua_State*L ) { |
1345 | struct s_lane *s; | 1352 | struct s_lane *s; |
1346 | 1353 | ||
1347 | STACK_GROW(L,1); | 1354 | STACK_GROW(L,1); |
@@ -1358,13 +1365,13 @@ static bool_t cancel_test( lua_State *L ) { | |||
1358 | return s && s->cancel_request; | 1365 | return s && s->cancel_request; |
1359 | } | 1366 | } |
1360 | 1367 | ||
1361 | static void cancel_error( lua_State *L ) { | 1368 | static void cancel_error( lua_State*L ) { |
1362 | STACK_GROW(L,1); | 1369 | STACK_GROW(L,1); |
1363 | lua_pushlightuserdata( L, CANCEL_ERROR ); // special error value | 1370 | lua_pushlightuserdata( L, CANCEL_ERROR ); // special error value |
1364 | lua_error(L); // no return | 1371 | lua_error(L); // no return |
1365 | } | 1372 | } |
1366 | 1373 | ||
1367 | static void cancel_hook( lua_State *L, lua_Debug *ar ) { | 1374 | static void cancel_hook( lua_State*L, lua_Debug *ar ) { |
1368 | (void)ar; | 1375 | (void)ar; |
1369 | if (cancel_test(L)) cancel_error(L); | 1376 | if (cancel_test(L)) cancel_error(L); |
1370 | } | 1377 | } |
@@ -1546,19 +1553,39 @@ static int lane_error( lua_State* L) | |||
1546 | 1553 | ||
1547 | LUAG_FUNC( set_debug_threadname) | 1554 | LUAG_FUNC( set_debug_threadname) |
1548 | { | 1555 | { |
1549 | luaL_checktype( L, -1, LUA_TSTRING); | 1556 | struct s_lane* s = lua_touserdata( L, lua_upvalueindex( 1)); |
1550 | THREAD_SETNAME( lua_tostring( L, -1)); | 1557 | luaL_checktype( L, -1, LUA_TSTRING); // "name" |
1558 | // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... | ||
1559 | lua_pushlightuserdata( L, LG_set_debug_threadname); // "name" lud | ||
1560 | lua_pushvalue( L, -2); // "name" lud "name" | ||
1561 | lua_rawset( L, LUA_REGISTRYINDEX); // "name" | ||
1562 | s->debug_name = lua_tostring( L, -1); | ||
1563 | // keep a direct pointer on the string | ||
1564 | THREAD_SETNAME( s->debug_name); | ||
1551 | // to see VM name in Decoda debugger Virtual Machine window | 1565 | // to see VM name in Decoda debugger Virtual Machine window |
1552 | lua_setglobal( L, "decoda_name"); | 1566 | lua_setglobal( L, "decoda_name"); // |
1553 | return 0; | 1567 | return 0; |
1554 | } | 1568 | } |
1555 | 1569 | ||
1570 | #if HAVE_LANE_TRACKING | ||
1571 | static bool_t GTrackLanes = FALSE; | ||
1572 | #endif // HAVE_LANE_TRACKING | ||
1573 | |||
1556 | //--- | 1574 | //--- |
1557 | static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs) | 1575 | static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs) |
1558 | { | 1576 | { |
1559 | struct s_lane *s= (struct s_lane *)vs; | 1577 | struct s_lane *s= (struct s_lane *)vs; |
1560 | int rc, rc2; | 1578 | int rc, rc2; |
1561 | lua_State *L= s->L; | 1579 | lua_State*L= s->L; |
1580 | |||
1581 | #if HAVE_LANE_TRACKING | ||
1582 | if( GTrackLanes) | ||
1583 | { | ||
1584 | // If we track lanes, we add them right now to the list so that its traversal hits all known lanes | ||
1585 | // (else we get only the still running lanes for which GC was called, IOW not accessible anymore from a script) | ||
1586 | selfdestruct_add( s); | ||
1587 | } | ||
1588 | #endif // HAVE_LANE_TRACKING | ||
1562 | 1589 | ||
1563 | s->status= RUNNING; // PENDING -> RUNNING | 1590 | s->status= RUNNING; // PENDING -> RUNNING |
1564 | 1591 | ||
@@ -1569,7 +1596,8 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs) | |||
1569 | 1596 | ||
1570 | // Tie "set_debug_threadname()" to the state | 1597 | // Tie "set_debug_threadname()" to the state |
1571 | // | 1598 | // |
1572 | lua_pushcfunction( L, LG_set_debug_threadname); | 1599 | lua_pushlightuserdata( L, s); |
1600 | lua_pushcclosure( L, LG_set_debug_threadname, 1); | ||
1573 | lua_setglobal( L, "set_debug_threadname" ); | 1601 | lua_setglobal( L, "set_debug_threadname" ); |
1574 | 1602 | ||
1575 | // Tie "cancel_test()" to the state | 1603 | // Tie "cancel_test()" to the state |
@@ -1704,7 +1732,7 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void *vs) | |||
1704 | 1732 | ||
1705 | // helper function to require a module in the keeper states and in the target state | 1733 | // helper function to require a module in the keeper states and in the target state |
1706 | // source state contains module name at the top of the stack | 1734 | // source state contains module name at the top of the stack |
1707 | static void require_one_module( lua_State *L, lua_State *L2, bool_t _fatal) | 1735 | static void require_one_module( lua_State*L, lua_State*L2, bool_t _fatal) |
1708 | { | 1736 | { |
1709 | size_t len; | 1737 | size_t len; |
1710 | char const *name = lua_tolstring( L, -1, &len); | 1738 | char const *name = lua_tolstring( L, -1, &len); |
@@ -1728,7 +1756,7 @@ static void require_one_module( lua_State *L, lua_State *L2, bool_t _fatal) | |||
1728 | 1756 | ||
1729 | LUAG_FUNC( thread_new ) | 1757 | LUAG_FUNC( thread_new ) |
1730 | { | 1758 | { |
1731 | lua_State *L2; | 1759 | lua_State*L2; |
1732 | struct s_lane *s; | 1760 | struct s_lane *s; |
1733 | struct s_lane **ud; | 1761 | struct s_lane **ud; |
1734 | 1762 | ||
@@ -1918,6 +1946,7 @@ LUAG_FUNC( thread_new ) | |||
1918 | s->L= L2; | 1946 | s->L= L2; |
1919 | s->status= PENDING; | 1947 | s->status= PENDING; |
1920 | s->waiting_on = NULL; | 1948 | s->waiting_on = NULL; |
1949 | s->debug_name = NULL; | ||
1921 | s->cancel_request= FALSE; | 1950 | s->cancel_request= FALSE; |
1922 | 1951 | ||
1923 | #if THREADWAIT_METHOD == THREADWAIT_CONDVAR | 1952 | #if THREADWAIT_METHOD == THREADWAIT_CONDVAR |
@@ -1995,9 +2024,14 @@ LUAG_FUNC( thread_gc) | |||
1995 | } | 2024 | } |
1996 | else if( s->status < DONE) | 2025 | else if( s->status < DONE) |
1997 | { | 2026 | { |
1998 | // still running: will have to be cleaned up later | 2027 | #if HAVE_LANE_TRACKING |
1999 | selfdestruct_add( s); | 2028 | if( !GTrackLanes) |
2000 | assert( s->selfdestruct_next); | 2029 | #endif // HAVE_LANE_TRACKING |
2030 | { | ||
2031 | // still running: will have to be cleaned up later | ||
2032 | selfdestruct_add( s); | ||
2033 | assert( s->selfdestruct_next); | ||
2034 | } | ||
2001 | return 0; | 2035 | return 0; |
2002 | 2036 | ||
2003 | } | 2037 | } |
@@ -2008,6 +2042,14 @@ LUAG_FUNC( thread_gc) | |||
2008 | s->L = 0; | 2042 | s->L = 0; |
2009 | } | 2043 | } |
2010 | 2044 | ||
2045 | #if HAVE_LANE_TRACKING | ||
2046 | if( GTrackLanes) | ||
2047 | { | ||
2048 | // Lane was cleaned up, no need to handle at process termination | ||
2049 | selfdestruct_remove( s); | ||
2050 | } | ||
2051 | #endif // HAVE_LANE_TRACKING | ||
2052 | |||
2011 | // Clean up after a (finished) thread | 2053 | // Clean up after a (finished) thread |
2012 | // | 2054 | // |
2013 | #if THREADWAIT_METHOD == THREADWAIT_CONDVAR | 2055 | #if THREADWAIT_METHOD == THREADWAIT_CONDVAR |
@@ -2091,7 +2133,7 @@ static char const * thread_status_string( struct s_lane *s) | |||
2091 | return str; | 2133 | return str; |
2092 | } | 2134 | } |
2093 | 2135 | ||
2094 | static int push_thread_status( lua_State *L, struct s_lane *s) | 2136 | static int push_thread_status( lua_State*L, struct s_lane *s) |
2095 | { | 2137 | { |
2096 | char const * const str = thread_status_string( s); | 2138 | char const * const str = thread_status_string( s); |
2097 | ASSERT_L( str); | 2139 | ASSERT_L( str); |
@@ -2113,7 +2155,7 @@ LUAG_FUNC( thread_join) | |||
2113 | { | 2155 | { |
2114 | struct s_lane* const s = lua_toLane( L, 1); | 2156 | struct s_lane* const s = lua_toLane( L, 1); |
2115 | double wait_secs= luaL_optnumber(L,2,-1.0); | 2157 | double wait_secs= luaL_optnumber(L,2,-1.0); |
2116 | lua_State *L2= s->L; | 2158 | lua_State*L2= s->L; |
2117 | int ret; | 2159 | int ret; |
2118 | bool_t done; | 2160 | bool_t done; |
2119 | 2161 | ||
@@ -2329,6 +2371,37 @@ LUAG_FUNC( thread_index) | |||
2329 | return 0; | 2371 | return 0; |
2330 | } | 2372 | } |
2331 | 2373 | ||
2374 | #if HAVE_LANE_TRACKING | ||
2375 | //--- | ||
2376 | // threads() -> {}|nil | ||
2377 | // | ||
2378 | // Return a list of all known lanes | ||
2379 | LUAG_FUNC( threads) | ||
2380 | { | ||
2381 | int const top = lua_gettop( L); | ||
2382 | // List _all_ still running threads | ||
2383 | // | ||
2384 | MUTEX_LOCK( &selfdestruct_cs); | ||
2385 | if( selfdestruct_first != SELFDESTRUCT_END) | ||
2386 | { | ||
2387 | struct s_lane* s = selfdestruct_first; | ||
2388 | lua_newtable( L); // {} | ||
2389 | while( s != SELFDESTRUCT_END) | ||
2390 | { | ||
2391 | if( s->debug_name) | ||
2392 | lua_pushstring( L, s->debug_name); // {} "name" | ||
2393 | else | ||
2394 | lua_pushfstring( L, "Lane %p", s); // {} "name" | ||
2395 | push_thread_status( L, s); // {} "name" "status" | ||
2396 | lua_rawset( L, -3); // {} | ||
2397 | s = s->selfdestruct_next; | ||
2398 | } | ||
2399 | } | ||
2400 | MUTEX_UNLOCK( &selfdestruct_cs); | ||
2401 | return lua_gettop( L) - top; | ||
2402 | } | ||
2403 | #endif // HAVE_LANE_TRACKING | ||
2404 | |||
2332 | /* | 2405 | /* |
2333 | * ############################################################################################### | 2406 | * ############################################################################################### |
2334 | * ######################################## Timer support ######################################## | 2407 | * ######################################## Timer support ######################################## |
@@ -2401,6 +2474,9 @@ LUAG_FUNC( wakeup_conv ) | |||
2401 | static const struct luaL_Reg lanes_functions [] = { | 2474 | static const struct luaL_Reg lanes_functions [] = { |
2402 | {"linda", LG_linda}, | 2475 | {"linda", LG_linda}, |
2403 | {"now_secs", LG_now_secs}, | 2476 | {"now_secs", LG_now_secs}, |
2477 | #if HAVE_LANE_TRACKING | ||
2478 | {"threads", LG_threads}, | ||
2479 | #endif // HAVE_LANE_TRACKING | ||
2404 | {"wakeup_conv", LG_wakeup_conv}, | 2480 | {"wakeup_conv", LG_wakeup_conv}, |
2405 | {"nameof", luaG_nameof}, | 2481 | {"nameof", luaG_nameof}, |
2406 | {"set_singlethreaded", LG_set_singlethreaded}, | 2482 | {"set_singlethreaded", LG_set_singlethreaded}, |
@@ -2410,7 +2486,7 @@ static const struct luaL_Reg lanes_functions [] = { | |||
2410 | /* | 2486 | /* |
2411 | * One-time initializations | 2487 | * One-time initializations |
2412 | */ | 2488 | */ |
2413 | static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_ref, int const nbKeepers, lua_CFunction _on_state_create, lua_Number _shutdown_timeout) | 2489 | static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_ref, int const nbKeepers, lua_CFunction _on_state_create, lua_Number _shutdown_timeout, bool_t _track_lanes) |
2414 | { | 2490 | { |
2415 | const char *err; | 2491 | const char *err; |
2416 | 2492 | ||
@@ -2421,7 +2497,11 @@ static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_r | |||
2421 | #if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) | 2497 | #if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) |
2422 | chudInitialize(); | 2498 | chudInitialize(); |
2423 | #endif | 2499 | #endif |
2424 | 2500 | ||
2501 | #if HAVE_LANE_TRACKING | ||
2502 | GTrackLanes = _track_lanes; | ||
2503 | #endif // HAVE_LANE_TRACKING | ||
2504 | |||
2425 | // Locks for 'tools.c' inc/dec counters | 2505 | // Locks for 'tools.c' inc/dec counters |
2426 | // | 2506 | // |
2427 | MUTEX_INIT( &deep_lock ); | 2507 | MUTEX_INIT( &deep_lock ); |
@@ -2516,6 +2596,7 @@ LUAG_FUNC( configure ) | |||
2516 | int const nbKeepers = (int)lua_tointeger( L, 1); | 2596 | int const nbKeepers = (int)lua_tointeger( L, 1); |
2517 | lua_CFunction on_state_create = lua_iscfunction( L, 2) ? lua_tocfunction( L, 2) : NULL; | 2597 | lua_CFunction on_state_create = lua_iscfunction( L, 2) ? lua_tocfunction( L, 2) : NULL; |
2518 | lua_Number shutdown_timeout = lua_tonumber( L, 3); | 2598 | lua_Number shutdown_timeout = lua_tonumber( L, 3); |
2599 | bool_t track_lanes = lua_toboolean( L, 4); | ||
2519 | /* | 2600 | /* |
2520 | * Making one-time initializations. | 2601 | * Making one-time initializations. |
2521 | * | 2602 | * |
@@ -2528,7 +2609,7 @@ LUAG_FUNC( configure ) | |||
2528 | static volatile int /*bool*/ go_ahead; // = 0 | 2609 | static volatile int /*bool*/ go_ahead; // = 0 |
2529 | if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0) | 2610 | if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0) |
2530 | { | 2611 | { |
2531 | init_once_LOCKED( L, &timer_deep, nbKeepers, on_state_create, shutdown_timeout); | 2612 | init_once_LOCKED( L, &timer_deep, nbKeepers, on_state_create, shutdown_timeout, track_lanes); |
2532 | go_ahead= 1; // let others pass | 2613 | go_ahead= 1; // let others pass |
2533 | } | 2614 | } |
2534 | else | 2615 | else |
@@ -2546,7 +2627,7 @@ LUAG_FUNC( configure ) | |||
2546 | // | 2627 | // |
2547 | if( s_initCount == 0) | 2628 | if( s_initCount == 0) |
2548 | { | 2629 | { |
2549 | init_once_LOCKED( L, &timer_deep, nbKeepers, on_state_create, shutdown_timeout); | 2630 | init_once_LOCKED( L, &timer_deep, nbKeepers, on_state_create, shutdown_timeout, track_lanes); |
2550 | s_initCount = 1; | 2631 | s_initCount = 1; |
2551 | } | 2632 | } |
2552 | } | 2633 | } |
@@ -2569,7 +2650,7 @@ LUAG_FUNC( configure ) | |||
2569 | lua_newtable( L); | 2650 | lua_newtable( L); |
2570 | lua_pushcfunction( L, LG_thread_gc); | 2651 | lua_pushcfunction( L, LG_thread_gc); |
2571 | lua_setfield( L, -2, "__gc"); | 2652 | lua_setfield( L, -2, "__gc"); |
2572 | lua_pushcfunction( L, LG_thread_index); | 2653 | lua_pushcfunction( L, LG_thread_index); |
2573 | lua_setfield( L, -2, "__index"); | 2654 | lua_setfield( L, -2, "__index"); |
2574 | lua_getglobal( L, "error"); | 2655 | lua_getglobal( L, "error"); |
2575 | ASSERT_L( lua_isfunction( L, -1)); | 2656 | ASSERT_L( lua_isfunction( L, -1)); |