aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2011-03-30 19:16:39 +0200
committerBenoit Germain <bnt.germain@gmail.com>2011-03-30 19:44:17 +0200
commit2d5d798c24286f10c1bffd5ea4ac466c2c3a12fa (patch)
tree17cdd59743fde2e33361509e5e5b847c0b816926 /src
parent5499ec1a61be9797c57834618a49731952b1d212 (diff)
downloadlanes-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.lua22
-rw-r--r--src/lanes.c136
-rw-r--r--src/lanes.lua9
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--
43local table_remove= assert( table.remove ) 43local table_concat = assert( table.concat)
44local table_concat= assert( table.concat ) 44local table_insert = assert( table.insert)
45local table_remove = assert( table.remove)
45 46
46--[[ 47--[[
47local function WR(...) 48local function WR(...)
@@ -230,6 +231,21 @@ end
230 231
231 232
232----- 233-----
234-- [val]= keys( linda_deep_ud)
235--
236function 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
245end
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
242end 258end
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*/
544LUAG_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*/
644LUAG_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*/
662LUAG_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
227end 229end
228 230
@@ -237,6 +239,8 @@ linda = mm.linda
237 239
238 240
239---=== Timers ===--- 241---=== Timers ===---
242local want_timers = true
243if want_timers then
240 244
241local timer_gateway= assert( mm.timer_gateway ) 245local 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 )
453end 457end
454 458
459end -- want_timers
455 460
456---=== Lock & atomic generators ===--- 461---=== Lock & atomic generators ===---
457 462