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 | ||
