aboutsummaryrefslogtreecommitdiff
path: root/src/tools.c
diff options
context:
space:
mode:
authorBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2013-10-11 20:08:32 +0200
committerBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2013-10-11 20:08:32 +0200
commit44540b9335f3bbd2f6fda3e13329b28ec76b6d7a (patch)
tree4b6d659c0976e58f6cbd907b673c2b9d769b9e88 /src/tools.c
parent938ee19cfcac09bfcfa1dd2a7861690436024410 (diff)
downloadlanes-44540b9335f3bbd2f6fda3e13329b28ec76b6d7a.tar.gz
lanes-44540b9335f3bbd2f6fda3e13329b28ec76b6d7a.tar.bz2
lanes-44540b9335f3bbd2f6fda3e13329b28ec76b6d7a.zip
version 3.7.0
* fix lanes.threads() not being available in a lane where lanes.configure() settings didn't contain track_lanes although the initial configure() call did. * require "lanes".configure() sequence is only necessary at the first require "lanes". * fix a crash at application shutdown where in some situations we could deinitialize the protected allocator mutex while a lane was still using it. * fix timers broken by change 69
Diffstat (limited to 'src/tools.c')
-rw-r--r--src/tools.c96
1 files changed, 68 insertions, 28 deletions
diff --git a/src/tools.c b/src/tools.c
index b02177b..95104d6 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -44,9 +44,31 @@ THE SOFTWARE.
44#include <stdlib.h> 44#include <stdlib.h>
45#include <malloc.h> 45#include <malloc.h>
46 46
47/*
48 * ###############################################################################################
49 * ########################################### ASSERT ############################################
50 * ###############################################################################################
51 */
52void ASSERT_IMPL( lua_State* L, bool_t cond_, char const* file_, int const line_, char const* text_)
53{
54 if ( !cond_)
55 {
56 (void) luaL_error( L, "ASSERT failed: %s:%d '%s'", file_, line_, text_);
57 }
58}
59
47// for verbose errors 60// for verbose errors
48bool_t GVerboseErrors = FALSE; 61bool_t GVerboseErrors = FALSE;
49 62
63char const* const CONFIG_REGKEY = "ee932492-a654-4506-9da8-f16540bdb5d4";
64char const* const LOOKUP_REGKEY = "ddea37aa-50c7-4d3f-8e0b-fb7a9d62bac5";
65
66/*
67 * ###############################################################################################
68 * ######################################### Lua 5.1/5.2 #########################################
69 * ###############################################################################################
70 */
71
50/* 72/*
51** Copied from Lua 5.2 loadlib.c 73** Copied from Lua 5.2 loadlib.c
52*/ 74*/
@@ -137,6 +159,19 @@ void luaG_dump( lua_State* L ) {
137 fprintf( stderr, "\n" ); 159 fprintf( stderr, "\n" );
138} 160}
139 161
162// just like lua_xmove, args are (from, to)
163void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_)
164{
165 STACK_GROW( L, 1);
166 // copy settings from from source to destination registry
167 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY);
168 if( luaG_inter_move( L, L2, 1, eLM_LaneBody) < 0) // error?
169 {
170 (void) luaL_error( L, "failed to copy settings when loading %s", name_);
171 }
172 lua_setfield( L2, LUA_REGISTRYINDEX, CONFIG_REGKEY);
173}
174
140 175
141/*---=== luaG_newstate ===---*/ 176/*---=== luaG_newstate ===---*/
142 177
@@ -171,24 +206,31 @@ static const luaL_Reg libs[] =
171 { NULL, NULL } 206 { NULL, NULL }
172}; 207};
173 208
174static void open1lib( lua_State* L, char const* name, size_t len) 209static void open1lib( lua_State* L, char const* name_, size_t len_, lua_State* from_)
175{ 210{
176 int i; 211 int i;
177 for( i = 0; libs[i].name; ++ i) 212 for( i = 0; libs[i].name; ++ i)
178 { 213 {
179 if( strncmp( name, libs[i].name, len) == 0) 214 if( strncmp( name_, libs[i].name, len_) == 0)
180 { 215 {
181 lua_CFunction libfunc = libs[i].func; 216 lua_CFunction libfunc = libs[i].func;
182 if( libfunc) 217 name_ = libs[i].name; // note that the provided name_ doesn't necessarily ends with '\0', hence len_
218 if( libfunc != NULL)
183 { 219 {
184 bool_t createGlobal = (libfunc != require_lanes_core) ? TRUE : FALSE; // don't want to create a global for "lanes.core" 220 bool_t const isLanesCore = (libfunc == require_lanes_core) ? TRUE : FALSE; // don't want to create a global for "lanes.core"
185 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, len, name)); 221 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, len_, name_));
186 STACK_CHECK( L); 222 STACK_CHECK( L);
223 if( isLanesCore == TRUE)
224 {
225 // copy settings from from source to destination registry
226 luaG_copy_one_time_settings( from_, L, name_);
227 }
187 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) 228 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack)
188 luaL_requiref( L, libs[i].name, libfunc, createGlobal); 229 luaL_requiref( L, name_, libfunc, !isLanesCore);
189 if( createGlobal == FALSE) 230 // lanes.core doesn't declare a global, so scan it here and now
231 if( isLanesCore == TRUE)
190 { 232 {
191 populate_func_lookup_table( L, -1, name); 233 populate_func_lookup_table( L, -1, name_);
192 } 234 }
193 lua_pop( L, 1); 235 lua_pop( L, 1);
194 STACK_END( L, 0); 236 STACK_END( L, 0);
@@ -473,14 +515,8 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
473 DEBUGSPEW_CODE( ++ debugspew_indent_depth); 515 DEBUGSPEW_CODE( ++ debugspew_indent_depth);
474 STACK_GROW( L, 3); 516 STACK_GROW( L, 3);
475 STACK_CHECK( L); 517 STACK_CHECK( L);
476 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY); // {}? 518 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {}
477 if( lua_isnil( L, -1)) // nil 519 ASSERT_L( lua_istable( L, -1));
478 {
479 lua_pop( L, 1); //
480 lua_newtable( L); // {}
481 lua_pushvalue( L, -1); // {} {}
482 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY); // {}
483 }
484 if( lua_type( L, in_base) == LUA_TFUNCTION) // for example when a module is a simple function 520 if( lua_type( L, in_base) == LUA_TFUNCTION) // for example when a module is a simple function
485 { 521 {
486 name_ = name_ ? name_ : "NULL"; 522 name_ = name_ ? name_ : "NULL";
@@ -538,17 +574,18 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con
538 lua_Alloc allocF = lua_getallocf( _from, &allocUD); 574 lua_Alloc allocF = lua_getallocf( _from, &allocUD);
539 lua_State* L = lua_newstate( allocF, allocUD); 575 lua_State* L = lua_newstate( allocF, allocUD);
540 576
541 if( !L) 577 if( L == NULL)
542 { 578 {
543 luaL_error( _from, "'lua_newstate()' failed; out of memory"); 579 (void) luaL_error( _from, "'lua_newstate()' failed; out of memory");
544 } 580 }
545 581
546 // neither libs (not even 'base') nor special init func: we are done 582 // neither libs (not even 'base') nor special init func: we are done
547 if( libs == NULL && _on_state_create <= 0) 583 if( libs == NULL && _on_state_create <= 0)
548 { 584 {
585 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate(NULL)\n" INDENT_END));
549 return L; 586 return L;
550 } 587 }
551 // if we are here, no keeper state is involved (because libs == NULL when we init keepers) 588 // from this point, we are not creating a keeper state (because libs == NULL when we init keepers)
552 589
553 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END)); 590 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END));
554 DEBUGSPEW_CODE( ++ debugspew_indent_depth); 591 DEBUGSPEW_CODE( ++ debugspew_indent_depth);
@@ -556,12 +593,15 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con
556 STACK_GROW( L, 2); 593 STACK_GROW( L, 2);
557 STACK_CHECK( L); 594 STACK_CHECK( L);
558 // 'lua.c' stops GC during initialization so perhaps its a good idea. :) 595 // 'lua.c' stops GC during initialization so perhaps its a good idea. :)
559 // but do it after _on_state_create in case it does a lot of stuff...
560 lua_gc( L, LUA_GCSTOP, 0); 596 lua_gc( L, LUA_GCSTOP, 0);
561 597
598 // we'll need this everytime we transfer some C function from/to this state
599 lua_newtable( L);
600 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY);
601
562 // Anything causes 'base' to be taken in 602 // Anything causes 'base' to be taken in
563 // 603 //
564 if( libs) 604 if( libs != NULL)
565 { 605 {
566 // special "*" case (mainly to help with LuaJIT compatibility) 606 // special "*" case (mainly to help with LuaJIT compatibility)
567 // as we are called from luaopen_lanes_core() already, and that would deadlock 607 // as we are called from luaopen_lanes_core() already, and that would deadlock
@@ -570,7 +610,7 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con
570 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END)); 610 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END));
571 luaL_openlibs( L); 611 luaL_openlibs( L);
572 // don't forget lanes.core for regular lane states 612 // don't forget lanes.core for regular lane states
573 open1lib( L, "lanes.core", 10); 613 open1lib( L, "lanes.core", 10, _from);
574 libs = NULL; // done with libs 614 libs = NULL; // done with libs
575 } 615 }
576 else 616 else
@@ -604,7 +644,7 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con
604 while( isalnum( p[len]) || p[len] == '.') 644 while( isalnum( p[len]) || p[len] == '.')
605 ++ len; 645 ++ len;
606 // open library 646 // open library
607 open1lib( L, p, len); 647 open1lib( L, p, len, _from);
608 } 648 }
609 serialize_require( L); 649 serialize_require( L);
610 } 650 }
@@ -612,7 +652,7 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con
612 lua_gc( L, LUA_GCRESTART, 0); 652 lua_gc( L, LUA_GCRESTART, 0);
613 653
614 STACK_CHECK( L); 654 STACK_CHECK( L);
615 // call this after the base libraries are loaded! 655 // call this after the base libraries are loaded and GC is restarted
616 if( _on_state_create > 0) 656 if( _on_state_create > 0)
617 { 657 {
618 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); 658 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END));
@@ -633,7 +673,7 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con
633 // capture error and forward it to main state 673 // capture error and forward it to main state
634 if( lua_pcall( L, 0, 0, 0) != LUA_OK) 674 if( lua_pcall( L, 0, 0, 0) != LUA_OK)
635 { 675 {
636 luaL_error( _from, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1))); 676 (void) luaL_error( _from, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1)));
637 } 677 }
638 STACK_MID( L, 0); 678 STACK_MID( L, 0);
639 } 679 }
@@ -1486,7 +1526,7 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, enum eLoo
1486 else 1526 else
1487 { 1527 {
1488 // fetch the name from the source state's lookup table 1528 // fetch the name from the source state's lookup table
1489 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY); // ... f ... {} 1529 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // ... f ... {}
1490 ASSERT_L( lua_istable( L, -1)); 1530 ASSERT_L( lua_istable( L, -1));
1491 lua_pushvalue( L, i); // ... f ... {} f 1531 lua_pushvalue( L, i); // ... f ... {} f
1492 lua_rawget( L, -2); // ... f ... {} "f.q.n" 1532 lua_rawget( L, -2); // ... f ... {} "f.q.n"
@@ -1533,7 +1573,7 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, enum eLoo
1533 } 1573 }
1534 else 1574 else
1535 { 1575 {
1536 lua_getfield( L2, LUA_REGISTRYINDEX, LOOKUP_KEY); // {} 1576 lua_getfield( L2, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {}
1537 ASSERT_L( lua_istable( L2, -1)); 1577 ASSERT_L( lua_istable( L2, -1));
1538 lua_pushlstring( L2, fqn, len); // {} "f.q.n" 1578 lua_pushlstring( L2, fqn, len); // {} "f.q.n"
1539 lua_rawget( L2, -2); // {} f 1579 lua_rawget( L2, -2); // {} f
@@ -1923,7 +1963,7 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
1923 */ 1963 */
1924 if( inter_copy_one_( L2, L2_cache_i, L, val_i, VT_NORMAL, mode_, valPath)) 1964 if( inter_copy_one_( L2, L2_cache_i, L, val_i, VT_NORMAL, mode_, valPath))
1925 { 1965 {
1926 ASSERT_L( lua_istable(L2,-3)); 1966 ASSERT_L( lua_istable( L2, -3));
1927 lua_rawset( L2, -3); // add to table (pops key & val) 1967 lua_rawset( L2, -3); // add to table (pops key & val)
1928 } 1968 }
1929 else 1969 else