diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2011-03-30 19:16:39 +0200 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2011-03-30 19:44:17 +0200 |
commit | 2d5d798c24286f10c1bffd5ea4ac466c2c3a12fa (patch) | |
tree | 17cdd59743fde2e33361509e5e5b847c0b816926 /src | |
parent | 5499ec1a61be9797c57834618a49731952b1d212 (diff) | |
download | lanes-2d5d798c24286f10c1bffd5ea4ac466c2c3a12fa.tar.gz lanes-2d5d798c24286f10c1bffd5ea4ac466c2c3a12fa.tar.bz2 lanes-2d5d798c24286f10c1bffd5ea4ac466c2c3a12fa.zip |
New features
* linda honors __tostring and __concat
* new accessor linda:keys(), to retrieve the list of keys with pending data inside a linda
* new lanes options packagepath and packagecpath, in case one needs to set them differently than the default
Diffstat (limited to 'src')
-rw-r--r-- | src/keeper.lua | 22 | ||||
-rw-r--r-- | src/lanes.c | 136 | ||||
-rw-r--r-- | src/lanes.lua | 9 |
3 files changed, 158 insertions, 9 deletions
diff --git a/src/keeper.lua b/src/keeper.lua index 2c38c0b..4bb181a 100644 --- a/src/keeper.lua +++ b/src/keeper.lua | |||
@@ -40,8 +40,9 @@ assert( nil_sentinel ) | |||
40 | 40 | ||
41 | -- We only need to have base and table libraries (and io for debugging) | 41 | -- We only need to have base and table libraries (and io for debugging) |
42 | -- | 42 | -- |
43 | local table_remove= assert( table.remove ) | 43 | local table_concat = assert( table.concat) |
44 | local table_concat= assert( table.concat ) | 44 | local table_insert = assert( table.insert) |
45 | local table_remove = assert( table.remove) | ||
45 | 46 | ||
46 | --[[ | 47 | --[[ |
47 | local function WR(...) | 48 | local function WR(...) |
@@ -230,6 +231,21 @@ end | |||
230 | 231 | ||
231 | 232 | ||
232 | ----- | 233 | ----- |
234 | -- [val]= keys( linda_deep_ud) | ||
235 | -- | ||
236 | function keys( ud) | ||
237 | |||
238 | local data,_,_= tables(ud) | ||
239 | |||
240 | local out = {} | ||
241 | for key, v in pairs( data) do | ||
242 | table_insert( out, key) | ||
243 | end | ||
244 | return (#out > 0) and out or nil | ||
245 | end | ||
246 | |||
247 | |||
248 | ----- | ||
233 | -- void= clear( linda_deep_ud ) | 249 | -- void= clear( linda_deep_ud ) |
234 | -- | 250 | -- |
235 | -- Clear the data structures used for a Linda (at its destructor) | 251 | -- Clear the data structures used for a Linda (at its destructor) |
@@ -240,5 +256,3 @@ function clear( ud ) | |||
240 | _incoming[ud]= nil | 256 | _incoming[ud]= nil |
241 | _limits[ud]= nil | 257 | _limits[ud]= nil |
242 | end | 258 | end |
243 | |||
244 | |||
diff --git a/src/lanes.c b/src/lanes.c index 0c943aa..e06d367 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -537,6 +537,33 @@ LUAG_FUNC( linda_set) | |||
537 | 537 | ||
538 | 538 | ||
539 | /* | 539 | /* |
540 | * [val]= linda_keys( linda_ud) | ||
541 | * | ||
542 | * Get the list of keys with pending data in the linda | ||
543 | */ | ||
544 | LUAG_FUNC( linda_keys) | ||
545 | { | ||
546 | struct s_Linda *linda= lua_toLinda( L, 1); | ||
547 | int pushed; | ||
548 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | ||
549 | |||
550 | { | ||
551 | struct s_Keeper *K = keeper_acquire( linda); | ||
552 | pushed = keeper_call( K->L, "keys", L, linda, 2); | ||
553 | ASSERT_L( pushed==0 || pushed==1 ); | ||
554 | keeper_release(K); | ||
555 | // must trigger error after keeper state has been released | ||
556 | if( pushed < 0) | ||
557 | { | ||
558 | luaL_error( L, "tried to copy unsupported types"); | ||
559 | } | ||
560 | } | ||
561 | |||
562 | return pushed; | ||
563 | } | ||
564 | |||
565 | |||
566 | /* | ||
540 | * [val]= linda_get( linda_ud, key_num|str|bool|lightuserdata ) | 567 | * [val]= linda_get( linda_ud, key_num|str|bool|lightuserdata ) |
541 | * | 568 | * |
542 | * Get a value from Linda. | 569 | * Get a value from Linda. |
@@ -608,6 +635,57 @@ LUAG_FUNC( linda_deep ) { | |||
608 | 635 | ||
609 | 636 | ||
610 | /* | 637 | /* |
638 | * string = linda:__tostring( linda_ud) | ||
639 | * | ||
640 | * Return the stringification of a linda | ||
641 | * | ||
642 | * Useful for concatenation or debugging purposes | ||
643 | */ | ||
644 | LUAG_FUNC( linda_tostring) | ||
645 | { | ||
646 | char text[32]; | ||
647 | struct s_Linda *linda = lua_toLinda( L, 1); | ||
648 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | ||
649 | sprintf( text, "linda: %p", linda); | ||
650 | lua_pushstring( L, text); | ||
651 | return 1; | ||
652 | } | ||
653 | |||
654 | |||
655 | /* | ||
656 | * string = linda:__concat( a, b) | ||
657 | * | ||
658 | * Return the concatenation of a pair of items, one of them being a linda | ||
659 | * | ||
660 | * Useful for concatenation or debugging purposes | ||
661 | */ | ||
662 | LUAG_FUNC( linda_concat) | ||
663 | { | ||
664 | struct s_Linda *linda1 = lua_toLinda( L, 1); | ||
665 | struct s_Linda *linda2 = lua_toLinda( L, 2); | ||
666 | // lua semantics should enforce that one of the parameters we got is a linda | ||
667 | luaL_argcheck( L, linda1 || linda2, 1, "expected a linda object!"); | ||
668 | // replace the lindas by their string equivalents in the stack | ||
669 | if ( linda1) | ||
670 | { | ||
671 | char text[32]; | ||
672 | sprintf( text, "linda: %p", linda1); | ||
673 | lua_pushstring( L, text); | ||
674 | lua_replace( L, 1); | ||
675 | } | ||
676 | if ( linda2) | ||
677 | { | ||
678 | char text[32]; | ||
679 | sprintf( text, "linda: %p", linda2); | ||
680 | lua_pushstring( L, text); | ||
681 | lua_replace( L, 2); | ||
682 | } | ||
683 | // concat the result | ||
684 | lua_concat( L, 2); | ||
685 | return 1; | ||
686 | } | ||
687 | |||
688 | /* | ||
611 | * Identity function of a shared userdata object. | 689 | * Identity function of a shared userdata object. |
612 | * | 690 | * |
613 | * lightuserdata= linda_id( "new" [, ...] ) | 691 | * lightuserdata= linda_id( "new" [, ...] ) |
@@ -678,17 +756,28 @@ static void linda_id( lua_State *L, char const * const which) | |||
678 | // metatable is its own index | 756 | // metatable is its own index |
679 | lua_pushvalue( L, -1); | 757 | lua_pushvalue( L, -1); |
680 | lua_setfield( L, -2, "__index"); | 758 | lua_setfield( L, -2, "__index"); |
759 | |||
681 | // protect metatable from external access | 760 | // protect metatable from external access |
682 | lua_pushboolean( L, 0); | 761 | lua_pushboolean( L, 0); |
683 | lua_setfield( L, -2, "__metatable"); | 762 | lua_setfield( L, -2, "__metatable"); |
763 | |||
764 | lua_pushcfunction( L, LG_linda_tostring); | ||
765 | lua_setfield( L, -2, "__tostring"); | ||
766 | |||
767 | lua_pushcfunction( L, LG_linda_concat); | ||
768 | lua_setfield( L, -2, "__concat"); | ||
769 | |||
684 | // | 770 | // |
685 | // [-1]: linda metatable | 771 | // [-1]: linda metatable |
686 | lua_pushcfunction( L, LG_linda_send ); | 772 | lua_pushcfunction( L, LG_linda_send ); |
687 | lua_setfield( L, -2, "send" ); | 773 | lua_setfield( L, -2, "send" ); |
688 | 774 | ||
689 | lua_pushcfunction( L, LG_linda_receive ); | 775 | lua_pushcfunction( L, LG_linda_receive ); |
690 | lua_setfield( L, -2, "receive" ); | 776 | lua_setfield( L, -2, "receive" ); |
691 | 777 | ||
778 | lua_pushcfunction( L, LG_linda_keys ); | ||
779 | lua_setfield( L, -2, "keys" ); | ||
780 | |||
692 | lua_pushcfunction( L, LG_linda_limit ); | 781 | lua_pushcfunction( L, LG_linda_limit ); |
693 | lua_setfield( L, -2, "limit" ); | 782 | lua_setfield( L, -2, "limit" ); |
694 | 783 | ||
@@ -1359,6 +1448,7 @@ LUAG_FUNC( set_debug_threadname) | |||
1359 | // [cancelstep_uint=0], | 1448 | // [cancelstep_uint=0], |
1360 | // [prio_int=0], | 1449 | // [prio_int=0], |
1361 | // [globals_tbl], | 1450 | // [globals_tbl], |
1451 | // [packagepath], | ||
1362 | // [... args ...] ) | 1452 | // [... args ...] ) |
1363 | // | 1453 | // |
1364 | // Upvalues: metatable to use for 'lane_ud' | 1454 | // Upvalues: metatable to use for 'lane_ud' |
@@ -1373,8 +1463,10 @@ LUAG_FUNC( thread_new ) | |||
1373 | uint_t cs= luaG_optunsigned( L, 3,0); | 1463 | uint_t cs= luaG_optunsigned( L, 3,0); |
1374 | int prio= (int)luaL_optinteger( L, 4,0); | 1464 | int prio= (int)luaL_optinteger( L, 4,0); |
1375 | uint_t glob= luaG_isany(L,5) ? 5:0; | 1465 | uint_t glob= luaG_isany(L,5) ? 5:0; |
1466 | uint_t ppath = luaG_isany(L,6) ? 6:0; | ||
1467 | uint_t pcpath = luaG_isany(L,7) ? 7:0; | ||
1376 | 1468 | ||
1377 | #define FIXED_ARGS (5) | 1469 | #define FIXED_ARGS (7) |
1378 | uint_t args= lua_gettop(L) - FIXED_ARGS; | 1470 | uint_t args= lua_gettop(L) - FIXED_ARGS; |
1379 | 1471 | ||
1380 | if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) | 1472 | if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) |
@@ -1424,6 +1516,44 @@ LUAG_FUNC( thread_new ) | |||
1424 | serialize_require( L2 ); | 1516 | serialize_require( L2 ); |
1425 | } | 1517 | } |
1426 | 1518 | ||
1519 | // package.path | ||
1520 | STACK_CHECK(L2) | ||
1521 | if( ppath) | ||
1522 | { | ||
1523 | if (lua_type(L,ppath) != LUA_TSTRING) | ||
1524 | luaL_error( L, "expected packagepath as string, got %s", luaG_typename(L,ppath)); | ||
1525 | lua_getglobal( L2, "package"); | ||
1526 | if( lua_isnil( L2, -1)) | ||
1527 | { | ||
1528 | lua_pop( L2, 1); | ||
1529 | luaL_error( L, "specifying a new path for packages, but lane doesn't load package library"); | ||
1530 | } | ||
1531 | lua_pushvalue( L, ppath); | ||
1532 | luaG_inter_move( L, L2, 1); // moves the new path to L2 | ||
1533 | lua_setfield( L2, -2, "path"); // set package.path | ||
1534 | lua_pop( L2, 1); | ||
1535 | } | ||
1536 | STACK_END(L2,0) | ||
1537 | |||
1538 | // package.cpath | ||
1539 | STACK_CHECK(L2) | ||
1540 | if( pcpath) | ||
1541 | { | ||
1542 | if (lua_type(L,pcpath) != LUA_TSTRING) | ||
1543 | luaL_error( L, "expected packagecpath as string, got %s", luaG_typename(L,pcpath)); | ||
1544 | lua_getglobal( L2, "package"); | ||
1545 | if( lua_isnil( L2, -1)) | ||
1546 | { | ||
1547 | lua_pop( L2, 1); | ||
1548 | luaL_error( L, "specifying a new cpath for packages, but lane doesn't load package library"); | ||
1549 | } | ||
1550 | lua_pushvalue( L, pcpath); | ||
1551 | luaG_inter_move( L, L2, 1); // moves the new cpath to L2 | ||
1552 | lua_setfield( L2, -2, "cpath"); // set package.cpath | ||
1553 | lua_pop( L2, 1); | ||
1554 | } | ||
1555 | STACK_END(L2,0) | ||
1556 | |||
1427 | // Lane main function | 1557 | // Lane main function |
1428 | // | 1558 | // |
1429 | STACK_CHECK(L) | 1559 | STACK_CHECK(L) |
diff --git a/src/lanes.lua b/src/lanes.lua index 05c2ff1..252d151 100644 --- a/src/lanes.lua +++ b/src/lanes.lua | |||
@@ -204,7 +204,7 @@ function gen( ... ) | |||
204 | end | 204 | end |
205 | end | 205 | end |
206 | 206 | ||
207 | local prio, cs, g_tbl | 207 | local prio, cs, g_tbl, packagepath, packagecpath |
208 | 208 | ||
209 | for k,v in pairs(opt) do | 209 | for k,v in pairs(opt) do |
210 | if k=="priority" then prio= v | 210 | if k=="priority" then prio= v |
@@ -213,6 +213,8 @@ function gen( ... ) | |||
213 | type(v)=="number" and v or | 213 | type(v)=="number" and v or |
214 | error( "Bad cancelstep: "..tostring(v), lev ) | 214 | error( "Bad cancelstep: "..tostring(v), lev ) |
215 | elseif k=="globals" then g_tbl= v | 215 | elseif k=="globals" then g_tbl= v |
216 | elseif k=="packagepath" then packagepath= v | ||
217 | elseif k=="packagecpath" then packagecpath= v | ||
216 | --.. | 218 | --.. |
217 | elseif k==1 then error( "unkeyed option: ".. tostring(v), lev ) | 219 | elseif k==1 then error( "unkeyed option: ".. tostring(v), lev ) |
218 | else error( "Bad option: ".. tostring(k), lev ) | 220 | else error( "Bad option: ".. tostring(k), lev ) |
@@ -222,7 +224,7 @@ function gen( ... ) | |||
222 | -- Lane generator | 224 | -- Lane generator |
223 | -- | 225 | -- |
224 | return function(...) | 226 | return function(...) |
225 | return thread_new( func, libs, cs, prio, g_tbl, ...) -- args | 227 | return thread_new( func, libs, cs, prio, g_tbl, packagepath, packagecpath, ...) -- args |
226 | end | 228 | end |
227 | end | 229 | end |
228 | 230 | ||
@@ -237,6 +239,8 @@ linda = mm.linda | |||
237 | 239 | ||
238 | 240 | ||
239 | ---=== Timers ===--- | 241 | ---=== Timers ===--- |
242 | local want_timers = true | ||
243 | if want_timers then | ||
240 | 244 | ||
241 | local timer_gateway= assert( mm.timer_gateway ) | 245 | local timer_gateway= assert( mm.timer_gateway ) |
242 | -- | 246 | -- |
@@ -452,6 +456,7 @@ function timer( linda, key, a, period ) | |||
452 | timer_gateway:send( TGW_KEY, linda, key, wakeup_at, period ) | 456 | timer_gateway:send( TGW_KEY, linda, key, wakeup_at, period ) |
453 | end | 457 | end |
454 | 458 | ||
459 | end -- want_timers | ||
455 | 460 | ||
456 | ---=== Lock & atomic generators ===--- | 461 | ---=== Lock & atomic generators ===--- |
457 | 462 | ||