diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2012-08-14 22:01:15 +0200 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2012-08-14 22:01:15 +0200 |
commit | 617654ed50e39412cc04922874364daa47966678 (patch) | |
tree | 01644ba218b0cccd66026e696f17c66c9e89c9d3 | |
parent | 7767a0133c5c8945a887b06061aae332446f37bb (diff) | |
download | lanes-617654ed50e39412cc04922874364daa47966678.tar.gz lanes-617654ed50e39412cc04922874364daa47966678.tar.bz2 lanes-617654ed50e39412cc04922874364daa47966678.zip |
code updated to build against Lua 5.1 and Lua 5.2v3.1.6
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | docs/index.html | 8 | ||||
-rw-r--r-- | src/keeper.c | 2 | ||||
-rw-r--r-- | src/lanes.c | 33 | ||||
-rw-r--r-- | src/tools.c | 14 | ||||
-rw-r--r-- | src/tools.h | 27 |
6 files changed, 60 insertions, 28 deletions
@@ -1,5 +1,9 @@ | |||
1 | CHANGES: | 1 | CHANGES: |
2 | 2 | ||
3 | CHANGE 44: BGe 13-Aug-2012 | ||
4 | * lanes code updated to build against Lua 5.1 and Lua 5.2 | ||
5 | * removed the search for MSVCR80.DLL when building for MinGW32 since it no longer seems to be necessary | ||
6 | |||
3 | CHANGE 43: BGe 09-Aug-2012 | 7 | CHANGE 43: BGe 09-Aug-2012 |
4 | * fix possible crash at application shutdown when a race condition causes linda objects to be collected after the keeper states are cleaned up. | 8 | * fix possible crash at application shutdown when a race condition causes linda objects to be collected after the keeper states are cleaned up. |
5 | 9 | ||
diff --git a/docs/index.html b/docs/index.html index f082156..4e37fe6 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -55,8 +55,8 @@ | |||
55 | <!-- ... --> | 55 | <!-- ... --> |
56 | 56 | ||
57 | <p><br/><font size="-1"><i>Copyright © 2007-12 Asko Kauppi, Benoit Germain. All rights reserved.</i> | 57 | <p><br/><font size="-1"><i>Copyright © 2007-12 Asko Kauppi, Benoit Germain. All rights reserved.</i> |
58 | <br>Lua Lanes is published under the same <A HREF="http://en.wikipedia.org/wiki/MIT_License">MIT license</A> as Lua 5.1. | 58 | <br>Lua Lanes is published under the same <A HREF="http://en.wikipedia.org/wiki/MIT_License">MIT license</A> as Lua 5.1 and 5.2. |
59 | </p><p>This document was revised on 09-Jul-12, and applies to version 3.1.5 | 59 | </p><p>This document was revised on 13-Aug-12, and applies to version 3.1.6 |
60 | </font></p> | 60 | </font></p> |
61 | 61 | ||
62 | </center> | 62 | </center> |
@@ -75,6 +75,8 @@ | |||
75 | <tt>require "lanes"</tt> method. No C side programming is needed; all APIs are Lua side, and most existing extension modules should | 75 | <tt>require "lanes"</tt> method. No C side programming is needed; all APIs are Lua side, and most existing extension modules should |
76 | work seamlessly together with the multiple lanes. | 76 | work seamlessly together with the multiple lanes. |
77 | </p><p> | 77 | </p><p> |
78 | Starting with version 3.1.6, Lanes should build and run identically with either Lua 5.1 or Lua 5.2. | ||
79 | </p><p> | ||
78 | See <A HREF="comparison.html">comparison</A> of Lua Lanes with other Lua multithreading solutions. | 80 | See <A HREF="comparison.html">comparison</A> of Lua Lanes with other Lua multithreading solutions. |
79 | </p><p> | 81 | </p><p> |
80 | <h3>Features:</h3> | 82 | <h3>Features:</h3> |
@@ -281,7 +283,7 @@ also in the new lanes. | |||
281 | <td><tt>"base"</tt> or <tt>""</tt></td><td/> | 283 | <td><tt>"base"</tt> or <tt>""</tt></td><td/> |
282 | <td>root level names, <tt>print</tt>, <tt>assert</tt>, <tt>unpack</tt> etc.</td> | 284 | <td>root level names, <tt>print</tt>, <tt>assert</tt>, <tt>unpack</tt> etc.</td> |
283 | </tr> | 285 | </tr> |
284 | <tr><td/><td><tt>"coroutine"</tt></td><td/><td><tt>coroutine.*</tt> namespace <font size="-1">(part of base in Lua 5.1)</font></td></tr> | 286 | <tr><td/><td><tt>"coroutine"</tt></td><td/><td><tt>coroutine.*</tt> namespace <font size="-1">(part of base in Lua 5.1 and 5.2)</font></td></tr> |
285 | <tr><td/><td><tt>"debug"</tt></td><td/><td><tt>debug.*</tt> namespace</td></tr> | 287 | <tr><td/><td><tt>"debug"</tt></td><td/><td><tt>debug.*</tt> namespace</td></tr> |
286 | <tr><td/><td><tt>"io"</tt></td><td/><td><tt>io.*</tt> namespace</td></tr> | 288 | <tr><td/><td><tt>"io"</tt></td><td/><td><tt>io.*</tt> namespace</td></tr> |
287 | <tr><td/><td><tt>"math"</tt></td><td/><td><tt>math.*</tt> namespace</td></tr> | 289 | <tr><td/><td><tt>"math"</tt></td><td/><td><tt>math.*</tt> namespace</td></tr> |
diff --git a/src/keeper.c b/src/keeper.c index 2629485..444a98e 100644 --- a/src/keeper.c +++ b/src/keeper.c | |||
@@ -116,7 +116,7 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create) | |||
116 | lua_setglobal( K, "decoda_name"); | 116 | lua_setglobal( K, "decoda_name"); |
117 | 117 | ||
118 | // use package.loaders[2] to find keeper microcode | 118 | // use package.loaders[2] to find keeper microcode |
119 | lua_getfield( K, LUA_GLOBALSINDEX, "package"); // package | 119 | lua_getglobal( K, "package"); // package |
120 | lua_getfield( K, -1, "loaders"); // package package.loaders | 120 | lua_getfield( K, -1, "loaders"); // package package.loaders |
121 | lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2] | 121 | lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2] |
122 | lua_pushliteral( K, "lanes-keeper"); // package package.loaders package.loaders[2] "lanes-keeper" | 122 | lua_pushliteral( K, "lanes-keeper"); // package package.loaders package.loaders[2] "lanes-keeper" |
diff --git a/src/lanes.c b/src/lanes.c index 360990a..84f23e3 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -51,7 +51,7 @@ | |||
51 | * ... | 51 | * ... |
52 | */ | 52 | */ |
53 | 53 | ||
54 | char const* VERSION = "3.1.5"; | 54 | char const* VERSION = "3.1.6"; |
55 | 55 | ||
56 | /* | 56 | /* |
57 | =============================================================================== | 57 | =============================================================================== |
@@ -928,7 +928,7 @@ LUAG_FUNC( set_finalizer ) | |||
928 | // | 928 | // |
929 | push_registry_table( L, FINALIZER_REG_KEY, TRUE /*do create if none*/ ); | 929 | push_registry_table( L, FINALIZER_REG_KEY, TRUE /*do create if none*/ ); |
930 | 930 | ||
931 | lua_pushinteger( L, lua_objlen(L,-1)+1 ); | 931 | lua_pushinteger( L, lua_rawlen(L,-1)+1 ); |
932 | lua_pushvalue( L, 1 ); // copy of the function | 932 | lua_pushvalue( L, 1 ); // copy of the function |
933 | lua_settable( L, -3 ); | 933 | lua_settable( L, -3 ); |
934 | 934 | ||
@@ -966,7 +966,8 @@ static int run_finalizers( lua_State *L, int lua_rc ) | |||
966 | 966 | ||
967 | // [-1]: { func [, ...] } | 967 | // [-1]: { func [, ...] } |
968 | // | 968 | // |
969 | for( n= (unsigned int)lua_objlen(L,-1); n>0; n-- ) { | 969 | for( n = (unsigned int)lua_rawlen( L, -1); n > 0; -- n) |
970 | { | ||
970 | unsigned args= 0; | 971 | unsigned args= 0; |
971 | lua_pushinteger( L,n ); | 972 | lua_pushinteger( L,n ); |
972 | lua_gettable( L, -2 ); | 973 | lua_gettable( L, -2 ); |
@@ -1686,6 +1687,7 @@ LUAG_FUNC( thread_new ) | |||
1686 | if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); | 1687 | if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); |
1687 | 1688 | ||
1688 | STACK_GROW( L, 2); | 1689 | STACK_GROW( L, 2); |
1690 | STACK_GROW( L2, 3); | ||
1689 | 1691 | ||
1690 | ASSERT_L( lua_gettop(L2) == 0); | 1692 | ASSERT_L( lua_gettop(L2) == 0); |
1691 | 1693 | ||
@@ -1769,13 +1771,15 @@ LUAG_FUNC( thread_new ) | |||
1769 | luaL_error( L, "Expected table, got %s", luaL_typename(L,glob)); | 1771 | luaL_error( L, "Expected table, got %s", luaL_typename(L,glob)); |
1770 | 1772 | ||
1771 | lua_pushnil( L); | 1773 | lua_pushnil( L); |
1774 | lua_pushglobaltable( L2); // Lua 5.2 wants us to push the globals table on the stack | ||
1772 | while( lua_next( L, glob)) | 1775 | while( lua_next( L, glob)) |
1773 | { | 1776 | { |
1774 | luaG_inter_copy( L, L2, 2); // moves the key/value pair to the L2 stack | 1777 | luaG_inter_copy( L, L2, 2); // moves the key/value pair to the L2 stack |
1775 | // assign it in the globals table | 1778 | // assign it in L2's globals table |
1776 | lua_rawset( L2, LUA_GLOBALSINDEX); | 1779 | lua_rawset( L2, -3); |
1777 | lua_pop( L, 1); | 1780 | lua_pop( L, 1); |
1778 | } | 1781 | } |
1782 | lua_pop( L2, 1); | ||
1779 | 1783 | ||
1780 | STACK_END(L2, 0) | 1784 | STACK_END(L2, 0) |
1781 | STACK_END(L, 0) | 1785 | STACK_END(L, 0) |
@@ -1845,7 +1849,7 @@ LUAG_FUNC( thread_new ) | |||
1845 | // Clear environment for the userdata | 1849 | // Clear environment for the userdata |
1846 | // | 1850 | // |
1847 | lua_newtable( L); | 1851 | lua_newtable( L); |
1848 | lua_setfenv( L, -2); | 1852 | lua_setuservalue( L, -2); |
1849 | 1853 | ||
1850 | // Place 's' in registry, for 'cancel_test()' (even if 'cs'==0 we still | 1854 | // Place 's' in registry, for 'cancel_test()' (even if 'cs'==0 we still |
1851 | // do cancel tests at pending send/receive). | 1855 | // do cancel tests at pending send/receive). |
@@ -2134,7 +2138,7 @@ LUAG_FUNC( thread_index) | |||
2134 | // first, check that we don't already have an environment that holds the requested value | 2138 | // first, check that we don't already have an environment that holds the requested value |
2135 | { | 2139 | { |
2136 | // If key is found in the environment, return it | 2140 | // If key is found in the environment, return it |
2137 | lua_getfenv( L, UD); | 2141 | lua_getuservalue( L, UD); |
2138 | lua_pushvalue( L, KEY); | 2142 | lua_pushvalue( L, KEY); |
2139 | lua_rawget( L, ENV); | 2143 | lua_rawget( L, ENV); |
2140 | if( !lua_isnil( L, -1)) | 2144 | if( !lua_isnil( L, -1)) |
@@ -2324,7 +2328,7 @@ LUAG_FUNC( wakeup_conv ) | |||
2324 | /*---=== Module linkage ===--- | 2328 | /*---=== Module linkage ===--- |
2325 | */ | 2329 | */ |
2326 | 2330 | ||
2327 | static const struct luaL_reg lanes_functions [] = { | 2331 | static const struct luaL_Reg lanes_functions [] = { |
2328 | {"linda", LG_linda}, | 2332 | {"linda", LG_linda}, |
2329 | {"now_secs", LG_now_secs}, | 2333 | {"now_secs", LG_now_secs}, |
2330 | {"wakeup_conv", LG_wakeup_conv}, | 2334 | {"wakeup_conv", LG_wakeup_conv}, |
@@ -2485,7 +2489,8 @@ LUAG_FUNC( configure ) | |||
2485 | // remove configure() (this function) from the module interface | 2489 | // remove configure() (this function) from the module interface |
2486 | lua_pushnil( L); | 2490 | lua_pushnil( L); |
2487 | lua_setfield( L, -2, "configure"); | 2491 | lua_setfield( L, -2, "configure"); |
2488 | luaL_register(L, NULL, lanes_functions); | 2492 | // add functions to the module's table |
2493 | luaG_registerlibfuncs(L, lanes_functions); | ||
2489 | 2494 | ||
2490 | // metatable for threads | 2495 | // metatable for threads |
2491 | // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join } | 2496 | // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join } |
@@ -2495,10 +2500,10 @@ LUAG_FUNC( configure ) | |||
2495 | lua_setfield( L, -2, "__gc"); | 2500 | lua_setfield( L, -2, "__gc"); |
2496 | lua_pushcfunction( L, LG_thread_index); | 2501 | lua_pushcfunction( L, LG_thread_index); |
2497 | lua_setfield( L, -2, "__index"); | 2502 | lua_setfield( L, -2, "__index"); |
2498 | lua_getfield( L, LUA_GLOBALSINDEX, "error"); | 2503 | lua_getglobal( L, "error"); |
2499 | ASSERT_L( lua_isfunction( L, -1)); | 2504 | ASSERT_L( lua_isfunction( L, -1)); |
2500 | lua_setfield( L, -2, "cached_error"); | 2505 | lua_setfield( L, -2, "cached_error"); |
2501 | lua_getfield( L, LUA_GLOBALSINDEX, "tostring"); | 2506 | lua_getglobal( L, "tostring"); |
2502 | ASSERT_L( lua_isfunction( L, -1)); | 2507 | ASSERT_L( lua_isfunction( L, -1)); |
2503 | lua_setfield( L, -2, "cached_tostring"); | 2508 | lua_setfield( L, -2, "cached_tostring"); |
2504 | lua_pushcfunction( L, LG_thread_join); | 2509 | lua_pushcfunction( L, LG_thread_join); |
@@ -2526,10 +2531,12 @@ LUAG_FUNC( configure ) | |||
2526 | // register all native functions found in that module in the transferable functions database | 2531 | // register all native functions found in that module in the transferable functions database |
2527 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) | 2532 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) |
2528 | populate_func_lookup_table( L, -1, name); | 2533 | populate_func_lookup_table( L, -1, name); |
2534 | lua_pop( L, 1); | ||
2529 | // record all existing C/JIT-fast functions | 2535 | // record all existing C/JIT-fast functions |
2530 | populate_func_lookup_table( L, LUA_GLOBALSINDEX, NULL); | 2536 | lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack |
2537 | populate_func_lookup_table( L, -1, NULL); | ||
2538 | lua_pop( L, 1); // done with globals table, pop it | ||
2531 | // Return nothing | 2539 | // Return nothing |
2532 | lua_pop( L, 1); | ||
2533 | return 0; | 2540 | return 0; |
2534 | } | 2541 | } |
2535 | 2542 | ||
diff --git a/src/tools.c b/src/tools.c index 65c70bf..c03433a 100644 --- a/src/tools.c +++ b/src/tools.c | |||
@@ -171,7 +171,7 @@ FuncSubType luaG_getfuncsubtype( lua_State *L, int _i) | |||
171 | } | 171 | } |
172 | { | 172 | { |
173 | int mustpush = 0, dumpres; | 173 | int mustpush = 0, dumpres; |
174 | if( STACK_ABS( L, _i) != lua_gettop( L)) | 174 | if( lua_absindex( L, _i) != lua_gettop( L)) |
175 | { | 175 | { |
176 | lua_pushvalue( L, _i); | 176 | lua_pushvalue( L, _i); |
177 | mustpush = 1; | 177 | mustpush = 1; |
@@ -376,7 +376,7 @@ static void populate_func_lookup_table_recur( lua_State *L, int _ctx_base, int _ | |||
376 | void populate_func_lookup_table( lua_State *L, int _i, char const *_name) | 376 | void populate_func_lookup_table( lua_State *L, int _i, char const *_name) |
377 | { | 377 | { |
378 | int const ctx_base = lua_gettop( L) + 1; | 378 | int const ctx_base = lua_gettop( L) + 1; |
379 | int const in_base = STACK_ABS( L, _i); | 379 | int const in_base = lua_absindex( L, _i); |
380 | int const start_depth = _name ? 1 : 0; | 380 | int const start_depth = _name ? 1 : 0; |
381 | //printf( "%p: populate_func_lookup_table('%s')\n", L, _name ? _name : "NULL"); | 381 | //printf( "%p: populate_func_lookup_table('%s')\n", L, _name ? _name : "NULL"); |
382 | STACK_GROW( L, 3); | 382 | STACK_GROW( L, 3); |
@@ -458,7 +458,9 @@ lua_State* luaG_newstate( char const* libs, lua_CFunction _on_state_create) | |||
458 | } | 458 | } |
459 | } | 459 | } |
460 | // after opening base, register the functions it exported in our name<->function database | 460 | // after opening base, register the functions it exported in our name<->function database |
461 | populate_func_lookup_table( L, LUA_GLOBALSINDEX, NULL); | 461 | lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack |
462 | populate_func_lookup_table( L, -1, NULL); | ||
463 | lua_pop( L, 1); | ||
462 | STACK_MID( L, 0); | 464 | STACK_MID( L, 0); |
463 | if( libs) | 465 | if( libs) |
464 | { | 466 | { |
@@ -594,7 +596,7 @@ luaG_IdFunction get_idfunc( lua_State *L, int index ) | |||
594 | { | 596 | { |
595 | luaG_IdFunction ret; | 597 | luaG_IdFunction ret; |
596 | 598 | ||
597 | index = STACK_ABS( L, index); | 599 | index = lua_absindex( L, index); |
598 | 600 | ||
599 | STACK_GROW(L,1); | 601 | STACK_GROW(L,1); |
600 | 602 | ||
@@ -1006,7 +1008,7 @@ uint_t get_mt_id( lua_State *L, int i ) { | |||
1006 | static uint_t last_id= 0; | 1008 | static uint_t last_id= 0; |
1007 | uint_t id; | 1009 | uint_t id; |
1008 | 1010 | ||
1009 | i = STACK_ABS( L, i); | 1011 | i = lua_absindex( L, i); |
1010 | 1012 | ||
1011 | STACK_GROW(L,3); | 1013 | STACK_GROW(L,3); |
1012 | 1014 | ||
@@ -1296,7 +1298,7 @@ int luaG_nameof( lua_State* L) | |||
1296 | // push a table whose contents are strings that, when concatenated, produce unique name | 1298 | // push a table whose contents are strings that, when concatenated, produce unique name |
1297 | lua_newtable( L); // o nil {c} {fqn} | 1299 | lua_newtable( L); // o nil {c} {fqn} |
1298 | // this is where we start the search | 1300 | // this is where we start the search |
1299 | lua_pushvalue( L, LUA_GLOBALSINDEX); // o nil {c} {fqn} _G | 1301 | lua_pushglobaltable( L); // o nil {c} {fqn} _G |
1300 | (void) discover_object_name_recur( L, 6666, 0); | 1302 | (void) discover_object_name_recur( L, 6666, 0); |
1301 | lua_pop( L, 3); // o "result" | 1303 | lua_pop( L, 3); // o "result" |
1302 | lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" | 1304 | lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" |
diff --git a/src/tools.h b/src/tools.h index b8dc362..43582c5 100644 --- a/src/tools.h +++ b/src/tools.h | |||
@@ -4,16 +4,33 @@ | |||
4 | #ifndef TOOLS_H | 4 | #ifndef TOOLS_H |
5 | #define TOOLS_H | 5 | #define TOOLS_H |
6 | 6 | ||
7 | #include "lua.h" | 7 | #include "lauxlib.h" |
8 | #include "threading.h" | 8 | #include "threading.h" |
9 | // MUTEX_T | 9 | // MUTEX_T |
10 | 10 | ||
11 | #include <assert.h> | 11 | #include <assert.h> |
12 | 12 | ||
13 | // Note: The < LUA_REGISTRYINDEX test is to leave registry/global/upvalue indices untouched | 13 | // M$ compiler doesn't support 'inline' keyword in C files... |
14 | // | 14 | #if defined( _MSC_VER) |
15 | #define /*int*/ STACK_ABS(L,n) \ | 15 | #define inline __inline |
16 | ( ((n) >= 0 || (n) <= LUA_REGISTRYINDEX) ? (n) : lua_gettop(L) +(n) +1 ) | 16 | #endif |
17 | |||
18 | // code is now using Lua 5.2 API | ||
19 | // add Lua 5.2 API when building for Lua 5.1 | ||
20 | #if LUA_VERSION_NUM == 501 | ||
21 | #define lua_absindex( L, idx) (((idx) >= 0 || (idx) <= LUA_REGISTRYINDEX) ? (idx) : lua_gettop(L) + (idx) +1) | ||
22 | #define lua_pushglobaltable(L) lua_pushvalue( L, LUA_GLOBALSINDEX) | ||
23 | #define lua_setuservalue lua_setfenv | ||
24 | #define lua_getuservalue lua_getfenv | ||
25 | #define lua_rawlen lua_objlen | ||
26 | #define luaG_registerlibfuncs( L, _funcs) luaL_register( L, NULL, _funcs) | ||
27 | #endif // LUA_VERSION_NUM == 501 | ||
28 | |||
29 | // wrap Lua 5.2 calls under Lua 5.1 API when it is simpler that way | ||
30 | #if LUA_VERSION_NUM == 502 | ||
31 | #define lua_equal( L, a, b) lua_compare( L, a, b, LUA_OPEQ) | ||
32 | #define luaG_registerlibfuncs( L, _funcs) luaL_setfuncs( L, _funcs, 0) | ||
33 | #endif // LUA_VERSION_NUM == 502 | ||
17 | 34 | ||
18 | #ifdef NDEBUG | 35 | #ifdef NDEBUG |
19 | #define _ASSERT_L(lua,c) /*nothing*/ | 36 | #define _ASSERT_L(lua,c) /*nothing*/ |