aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2013-01-26 20:21:39 +0100
committerBenoit Germain <bnt.germain@gmail.com>2013-01-26 20:21:39 +0100
commitfb0c67b1c95b6a595c0cd34a66136af6193b4d1b (patch)
treebadb5e95c0b7d9acb6be371c9163801b816b8731
parent68d8db431ec2b739dc53233d6b4d8aeee9324e48 (diff)
downloadlanes-fb0c67b1c95b6a595c0cd34a66136af6193b4d1b.tar.gz
lanes-fb0c67b1c95b6a595c0cd34a66136af6193b4d1b.tar.bz2
lanes-fb0c67b1c95b6a595c0cd34a66136af6193b4d1b.zip
version 3.4.4v3.4.4
* bugfix: take into account the fact that "coroutine" is no longer part of base library in Lua 5.2 * bugfix: if "bit32" was listed in the libraries, it wouldn't open (library list parsing failing on digits) * bugfix: Use luaL_requiref() to open standard libraries in Lua 5.2 as we should * bugfix: any Lua state created by Lanes reuses the allocator function of the originating state * bugfix: don't call on_state_create() while GC is suspended during lua state initialization
-rw-r--r--CHANGES12
-rw-r--r--docs/index.html2
-rw-r--r--src/keeper.c4
-rw-r--r--src/lanes.c8
-rw-r--r--src/tools.c172
-rw-r--r--src/tools.h2
-rw-r--r--tests/basic.lua89
7 files changed, 180 insertions, 109 deletions
diff --git a/CHANGES b/CHANGES
index 52ec52d..fc29440 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,15 +1,23 @@
1CHANGES: 1CHANGES:
2 2
3CHANGE 56: BGe 25-Jan-13
4 * version 3.4.4
5 * bugfix: take into account the fact that "coroutine" is no longer part of base library in Lua 5.2
6 * bugfix: if "bit32" was listed in the libraries, it wouldn't open (library list parsing failing on digits)
7 * bugfix: Use luaL_requiref() to open standard libraries in Lua 5.2 as we should
8 * bugfix: any Lua state created by Lanes reuses the allocator function of the originating state
9 * bugfix: don't call on_state_create() while GC is suspended during lua state initialization
10
3CHANGE 55: BGe 24-Jan-13 11CHANGE 55: BGe 24-Jan-13
4 * version 3.4.3 12 * version 3.4.3
5 * raise an error if lane generator libs specification contains a lib more than once 13 * raise an error if lane generator libs specification contains a lib more than once
6 * bit32 is a valid lib name in the libs specification (silently ignored by the Lua 5.1 build) 14 * bit32 is a valid lib name in the libs specification (silently ignored by the Lua 5.1 build)
7 * improved lanes.nameof to search inside table- and userdata- metatables for an object's name 15 * improved lanes.nameof to search inside table- and userdata- metatables for an object's name
8 * fixed an unwarranted error when trying to discover a function name upon a failed transfer 16 * bugfix: fixed an unwarranted error when trying to discover a function name upon a failed transfer
9 * contents of package.[path,cpath,preload,loaders|searchers] are pulled *only once* inside keeper states at initialisation 17 * contents of package.[path,cpath,preload,loaders|searchers] are pulled *only once* inside keeper states at initialisation
10 * Lua function upvalues equal to the global environment aren't copied by value, but bound to the destination's global environment 18 * Lua function upvalues equal to the global environment aren't copied by value, but bound to the destination's global environment
11 especially useful for Lua 5.2 _ENV 19 especially useful for Lua 5.2 _ENV
12 * fixed loading of base libraries that didn't create the global tables when built for Lua 5.2 20 * bugfix: fixed loading of base libraries that didn't create the global tables when built for Lua 5.2
13 21
14CHANGE 54: BGe 10-Jan-13 22CHANGE 54: BGe 10-Jan-13
15 * version 3.4.2 23 * version 3.4.2
diff --git a/docs/index.html b/docs/index.html
index 8188fe9..4f31923 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -69,7 +69,7 @@
69 </p> 69 </p>
70 70
71 <p> 71 <p>
72 This document was revised on 24-Jan-13, and applies to version <tt>3.4.3</tt>. 72 This document was revised on 26-Jan-13, and applies to version <tt>3.4.4</tt>.
73 </p> 73 </p>
74 </font> 74 </font>
75 </center> 75 </center>
diff --git a/src/keeper.c b/src/keeper.c
index a7c8647..516fe85 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -569,9 +569,7 @@ char const* init_keepers( lua_State* L, int const _nbKeepers, lua_CFunction _on_
569 // 569 //
570 // 'io' for debugging messages, 'package' because we need to require modules exporting idfuncs 570 // 'io' for debugging messages, 'package' because we need to require modules exporting idfuncs
571 // the others because they export functions that we may store in a keeper for transfer between lanes 571 // the others because they export functions that we may store in a keeper for transfer between lanes
572 lua_State* K = luaG_newstate( "*", _on_state_create); 572 lua_State* K = luaG_newstate( L, "*", _on_state_create);
573 if( !K)
574 return "out of memory";
575 573
576 DEBUGSPEW_CODE( fprintf( stderr, "init_keepers %d\n", i)); 574 DEBUGSPEW_CODE( fprintf( stderr, "init_keepers %d\n", i));
577 575
diff --git a/src/lanes.c b/src/lanes.c
index 6fec951..62d56c1 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -52,7 +52,7 @@
52 * ... 52 * ...
53 */ 53 */
54 54
55char const* VERSION = "3.4.3"; 55char const* VERSION = "3.4.4";
56 56
57/* 57/*
58=============================================================================== 58===============================================================================
@@ -1894,11 +1894,7 @@ LUAG_FUNC( thread_new )
1894 1894
1895 // populate with selected libraries at the same time 1895 // populate with selected libraries at the same time
1896 // 1896 //
1897 L2 = luaG_newstate( libs, on_state_create); 1897 L2 = luaG_newstate( L, libs, on_state_create);
1898 if (!L2)
1899 {
1900 return luaL_error( L, "'luaL_newstate()' failed; out of memory");
1901 }
1902 1898
1903 STACK_GROW( L, 2); 1899 STACK_GROW( L, 2);
1904 STACK_GROW( L2, 3); 1900 STACK_GROW( L2, 3);
diff --git a/src/tools.c b/src/tools.c
index fe1728d..ade8cb8 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -100,17 +100,19 @@ static const luaL_Reg libs[] =
100{ 100{
101 { LUA_LOADLIBNAME, luaopen_package}, 101 { LUA_LOADLIBNAME, luaopen_package},
102 { LUA_TABLIBNAME, luaopen_table}, 102 { LUA_TABLIBNAME, luaopen_table},
103 { LUA_IOLIBNAME, luaopen_io},
104 { LUA_OSLIBNAME, luaopen_os},
105 { LUA_STRLIBNAME, luaopen_string}, 103 { LUA_STRLIBNAME, luaopen_string},
106 { LUA_MATHLIBNAME, luaopen_math}, 104 { LUA_MATHLIBNAME, luaopen_math},
105 { LUA_OSLIBNAME, luaopen_os},
106 { LUA_IOLIBNAME, luaopen_io},
107#if LUA_VERSION_NUM >= 502 107#if LUA_VERSION_NUM >= 502
108 { LUA_BITLIBNAME, luaopen_bit32}, 108 { LUA_BITLIBNAME, luaopen_bit32},
109 { LUA_COLIBNAME, luaopen_coroutine}, // Lua 5.2: coroutine is no longer a part of base!
110#else // LUA_VERSION_NUM
111 { LUA_COLIBNAME, NULL}, // Lua 5.1: part of base package
109#endif // LUA_VERSION_NUM 112#endif // LUA_VERSION_NUM
110 { LUA_DBLIBNAME, luaopen_debug}, 113 { LUA_DBLIBNAME, luaopen_debug},
111 // 114 //
112 { "base", NULL }, // ignore "base" (already acquired it) 115 { "base", NULL}, // ignore "base" (already acquired it)
113 { LUA_COLIBNAME, NULL }, // part of Lua 5.[1|2] base package
114 { NULL, NULL } 116 { NULL, NULL }
115}; 117};
116 118
@@ -124,18 +126,16 @@ static void open1lib( lua_State* L, char const* name, size_t len)
124 if( libs[i].func) 126 if( libs[i].func)
125 { 127 {
126 DEBUGSPEW_CODE( fprintf( stderr, "opening %.*s library\n", len, name)); 128 DEBUGSPEW_CODE( fprintf( stderr, "opening %.*s library\n", len, name));
127 STACK_GROW( L, 1);
128 STACK_CHECK( L) 129 STACK_CHECK( L)
129 lua_pushcfunction( L, libs[i].func);
130 // pushes the module table on the stack
131 lua_call( L, 0, 1);
132 populate_func_lookup_table( L, -1, libs[i].name);
133#if LUA_VERSION_NUM >= 502 130#if LUA_VERSION_NUM >= 502
134 // Lua 5.2: luaopen_x doesn't create the global, we have to do it ourselves! 131 // open the library as if through require(), and create a global as well (the library table is left on the stack)
135 lua_setglobal( L, libs[i].name); 132 luaL_requiref( L, libs[i].name, libs[i].func, 1);
136#else // LUA_VERSION_NUM
137 // Lua 5.1: remove the module when we are done
138 lua_pop( L, 1); 133 lua_pop( L, 1);
134#else // LUA_VERSION_NUM
135 STACK_GROW( L, 1);
136 lua_pushcfunction( L, libs[i].func);
137 // pushes the module table on the stack
138 lua_call( L, 0, 0);
139#endif // LUA_VERSION_NUM 139#endif // LUA_VERSION_NUM
140 STACK_END( L, 0) 140 STACK_END( L, 0)
141 } 141 }
@@ -427,75 +427,93 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* _name)
427* 427*
428* Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL. 428* Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL.
429* 429*
430* Returns NULL for ok, position of error within 'libs' on failure.
431*/ 430*/
432#define is_name_char(c) (isalpha(c) || (c)=='*')
433 431
434lua_State* luaG_newstate( char const* libs, lua_CFunction _on_state_create) 432lua_State* luaG_newstate( lua_State* _from, char const* libs, lua_CFunction _on_state_create)
435{ 433{
436 lua_State* const L = luaL_newstate(); 434 // reuse alloc function from the originating state
435 void* allocUD;
436 lua_Alloc allocF = lua_getallocf( _from, &allocUD);
437 lua_State* L = lua_newstate( allocF, allocUD);
437 438
438 // no libs, or special init func (not even 'base') 439 if( !L)
439 if (libs || _on_state_create)
440 { 440 {
441 // 'lua.c' stops GC during initialization so perhaps its a good idea. :) 441 luaL_error( _from, "'lua_newstate()' failed; out of memory");
442 // 442 }
443 lua_gc( L, LUA_GCSTOP, 0);
444 443
445 // Anything causes 'base' to be taken in 444 // neither libs (not even 'base') nor special init func: we are done
446 // 445 if( !libs && !_on_state_create)
447 STACK_GROW( L, 2); 446 {
448 STACK_CHECK( L) 447 return L;
449 if( _on_state_create) 448 }
449
450 STACK_GROW( L, 2);
451 STACK_CHECK( L)
452 if( _on_state_create)
453 {
454 DEBUGSPEW_CODE( fprintf( stderr, "calling on_state_create()\n"));
455 lua_pushcfunction( L, _on_state_create);
456 lua_call( L, 0, 0);
457 }
458
459 // 'lua.c' stops GC during initialization so perhaps its a good idea. :)
460 // but do it after _on_state_create in case it does a lot of stuff...
461 lua_gc( L, LUA_GCSTOP, 0);
462
463 // Anything causes 'base' to be taken in
464 //
465 if( libs)
466 {
467 if( libs[0] == '*' && libs[1] == 0) // special "*" case (mainly to help with LuaJIT compatibility)
450 { 468 {
451 lua_pushcfunction( L, _on_state_create); 469 DEBUGSPEW_CODE( fprintf( stderr, "opening ALL standard libraries\n"));
452 lua_call( L, 0, 0); 470 luaL_openlibs( L);
471 libs = NULL; // done with libs
453 } 472 }
454 if( libs) 473 else
455 { 474 {
456 if( libs[0] == '*' && libs[1] == 0) // special "*" case (mainly to help with LuaJIT compatibility) 475 DEBUGSPEW_CODE( fprintf( stderr, "opening base library\n"));
457 { 476#if LUA_VERSION_NUM >= 502
458 DEBUGSPEW_CODE( fprintf( stderr, "opening ALL base libraries\n")); 477 // open base library the same way as in luaL_openlibs()
459 luaL_openlibs( L); 478 luaL_requiref( L, "_G", luaopen_base, 1);
460 libs = NULL; // done with libs 479 lua_pop( L, 1);
461 } 480#else // LUA_VERSION_NUM
462 else 481 lua_pushcfunction( L, luaopen_base);
463 { 482 lua_pushstring( L, "");
464 DEBUGSPEW_CODE( fprintf( stderr, "opening base library\n")); 483 lua_call( L, 1, 0);
465 lua_pushcfunction( L, luaopen_base); 484#endif // LUA_VERSION_NUM
466 lua_call( L, 0, 0);
467 }
468 } 485 }
486 }
487 STACK_END( L, 0)
469 488
470 // after opening base, register the functions it exported in our name<->function database 489 // scan all libraries, open them one by one
471 lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack 490 if( libs)
472 populate_func_lookup_table( L, -1, NULL); 491 {
473 lua_pop( L, 1); 492 char const* p;
474 493 unsigned int len = 0;
475 STACK_MID( L, 0); 494 for( p = libs; *p; p += len)
476 { 495 {
477 char const* p; 496 len = 0;
478 unsigned int len = 0; 497 // skip delimiters
479 if( libs) 498 while( *p && !isalnum( *p))
480 { 499 ++ p;
481 for( p = libs; *p; p += len) 500 // skip name
482 { 501 while( isalnum( p[len]))
483 len = 0; 502 ++ len;
484 // skip delimiters 503 // open library
485 while( *p && !is_name_char( *p)) 504 open1lib( L, p, len);
486 ++ p;
487 // skip name
488 while( is_name_char( p[len]))
489 ++ len;
490 // open library
491 open1lib( L, p, len);
492 }
493 serialize_require( L);
494 }
495 } 505 }
496 STACK_END(L,0) 506 serialize_require( L);
497 lua_gc( L, LUA_GCRESTART, 0);
498 } 507 }
508
509 lua_gc( L, LUA_GCRESTART, 0);
510
511 STACK_CHECK( L)
512 // after opening base, register the functions it exported in our name<->function database
513 lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack
514 populate_func_lookup_table( L, -1, NULL);
515 lua_pop( L, 1);
516 STACK_END( L, 0)
499 return L; 517 return L;
500} 518}
501 519
@@ -1895,25 +1913,23 @@ static int new_require( lua_State *L)
1895*/ 1913*/
1896void serialize_require( lua_State *L ) 1914void serialize_require( lua_State *L )
1897{ 1915{
1898 STACK_GROW(L,1); 1916 STACK_GROW( L, 1);
1899 STACK_CHECK(L) 1917 STACK_CHECK( L)
1900 1918
1901 // Check 'require' is there; if not, do nothing 1919 // Check 'require' is there; if not, do nothing
1902 // 1920 //
1903 lua_getglobal( L, "require" ); 1921 lua_getglobal( L, "require");
1904 if (lua_isfunction( L, -1 )) 1922 if( lua_isfunction( L, -1))
1905 { 1923 {
1906 // [-1]: original 'require' function 1924 // [-1]: original 'require' function
1907 1925 lua_pushcclosure( L, new_require, 1 /*upvalues*/);
1908 lua_pushcclosure( L, new_require, 1 /*upvalues*/ ); 1926 lua_setglobal( L, "require");
1909 lua_setglobal( L, "require" );
1910
1911 } 1927 }
1912 else 1928 else
1913 { 1929 {
1914 // [-1]: nil 1930 // [-1]: nil
1915 lua_pop(L,1); 1931 lua_pop( L, 1);
1916 } 1932 }
1917 1933
1918 STACK_END(L,0) 1934 STACK_END( L, 0)
1919} 1935}
diff --git a/src/tools.h b/src/tools.h
index d0169cf..e4fbd94 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -73,7 +73,7 @@ extern char const* debugspew_indent;
73 73
74void luaG_dump( lua_State* L ); 74void luaG_dump( lua_State* L );
75 75
76lua_State* luaG_newstate( char const* libs, lua_CFunction _on_state_create); 76lua_State* luaG_newstate( lua_State* _from, char const* libs, lua_CFunction _on_state_create);
77 77
78typedef struct { 78typedef struct {
79 volatile int refcount; 79 volatile int refcount;
diff --git a/tests/basic.lua b/tests/basic.lua
index c35f16a..1f4eb1e 100644
--- a/tests/basic.lua
+++ b/tests/basic.lua
@@ -54,8 +54,11 @@ tables_match= function( a, b )
54 return subtable( a, b ) and subtable( b, a ) 54 return subtable( a, b ) and subtable( b, a )
55end 55end
56 56
57--##############################################################
58--##############################################################
59--##############################################################
57 60
58PRINT( "---=== Tasking (basic) ===---") 61PRINT( "\n\n", "---=== Tasking (basic) ===---", "\n\n")
59 62
60local function task( a, b, c ) 63local function task( a, b, c )
61 set_debug_threadname( "task("..a..","..b..","..c..")") 64 set_debug_threadname( "task("..a..","..b..","..c..")")
@@ -98,8 +101,11 @@ assert( v2_hey == true )
98assert( lane1.status == "done" ) 101assert( lane1.status == "done" )
99assert( lane1.status == "done" ) 102assert( lane1.status == "done" )
100 103
104--##############################################################
105--##############################################################
106--##############################################################
101 107
102PRINT( "---=== Tasking (cancelling) ===---") 108PRINT( "\n\n", "---=== Tasking (cancelling) ===---", "\n\n")
103 109
104local task_launch2= lanes_gen( "", { cancelstep=100, globals={hey=true} }, task ) 110local task_launch2= lanes_gen( "", { cancelstep=100, globals={hey=true} }, task )
105 111
@@ -181,7 +187,11 @@ repeat until wait_receive_batched_lane.status == "cancelled"
181print "wait_receive_batched_lane is cancelled" 187print "wait_receive_batched_lane is cancelled"
182--################################################]] 188--################################################]]
183 189
184PRINT( "---=== Communications ===---") 190--##############################################################
191--##############################################################
192--##############################################################
193
194PRINT( "\n\n", "---=== Communications ===---", "\n\n")
185 195
186local function WR(...) io.stderr:write(...) end 196local function WR(...) io.stderr:write(...) end
187 197
@@ -246,28 +256,64 @@ assert( tables_match( a, {'a','b','c',d=10} ) )
246assert( PEEK() == nil ) 256assert( PEEK() == nil )
247SEND(4) 257SEND(4)
248 258
259-- wait
260linda: receive( 1, "wait")
261
262--##############################################################
263--##############################################################
264--##############################################################
249 265
250PRINT( "---=== Stdlib naming ===---") 266PRINT( "\n\n", "---=== Stdlib naming ===---", "\n\n")
251 267
252local function io_os_f() 268local function dump_g( _x)
253 assert(io) 269 assert(print)
254 assert(os) 270 print( "### dumping _G for '" .. _x .. "'")
255 assert(print) 271 for k, v in pairs( _G) do
256 return true 272 print( "\t" .. k .. ": " .. type( v))
273 end
274 return true
257end 275end
258 276
259local f1= lanes_gen( "io,os", io_os_f ) -- any delimiter will do 277local function io_os_f( _x)
260local f2= lanes_gen( "io+os", io_os_f ) 278 assert(print)
261local f3= lanes_gen( "io,os,base", io_os_f ) 279 print( "### checking io and os libs existence for '" .. _x .. "'")
280 assert(io)
281 assert(os)
282 return true
283end
284
285local function coro_f( _x)
286 assert(print)
287 print( "### checking coroutine lib existence for '" .. _x .. "'")
288 assert(coroutine)
289 return true
290end
262 291
263assert.fails( function() lanes_gen( "xxx", io_os_f ) end ) 292assert.fails( function() lanes_gen( "xxx", io_os_f ) end )
264 293
265assert( f1()[1] ) 294local stdlib_naming_tests =
266assert( f2()[1] ) 295{
267assert( f3()[1] ) 296 -- { "", dump_g},
297 -- { "coroutine", dump_g},
298 -- { "io", dump_g},
299 -- { "bit32", dump_g},
300 { "coroutine", coro_f},
301 { "*", io_os_f},
302 { "io,os", io_os_f},
303 { "io+os", io_os_f},
304 { "io,os,base", io_os_f},
305}
306
307for _, t in ipairs( stdlib_naming_tests) do
308 local f= lanes_gen( t[1], t[2]) -- any delimiter will do
309 assert( f(t[1])[1] )
310end
268 311
312--##############################################################
313--##############################################################
314--##############################################################
269 315
270PRINT( "---=== Comms criss cross ===---") 316PRINT( "\n\n", "---=== Comms criss cross ===---", "\n\n")
271 317
272-- We make two identical lanes, which are using the same Linda channel. 318-- We make two identical lanes, which are using the same Linda channel.
273-- 319--
@@ -293,7 +339,11 @@ local a,b= tc(linda, "A","B"), tc(linda, "B","A") -- launching two lanes, twis
293local _= a[1],b[1] -- waits until they are both ready 339local _= a[1],b[1] -- waits until they are both ready
294 340
295 341
296PRINT( "---=== Receive & send of code ===---") 342--##############################################################
343--##############################################################
344--##############################################################
345
346PRINT( "\n\n", "---=== Receive & send of code ===---", "\n\n")
297 347
298local upvalue="123" 348local upvalue="123"
299 349
@@ -351,8 +401,11 @@ assert( s2==":)" )
351local k,ok2= linda:receive( "up" ) 401local k,ok2= linda:receive( "up" )
352assert( ok2 == "ok2" ) 402assert( ok2 == "ok2" )
353 403
404--##############################################################
405--##############################################################
406--##############################################################
354 407
355PRINT( "---=== :join test ===---") 408PRINT( "\n\n", "---=== :join test ===---", "\n\n")
356 409
357-- NOTE: 'unpack()' cannot be used on the lane handle; it will always return nil 410-- NOTE: 'unpack()' cannot be used on the lane handle; it will always return nil
358-- (unless [1..n] has been read earlier, in which case it would seemingly 411-- (unless [1..n] has been read earlier, in which case it would seemingly