diff options
author | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-01-20 10:51:11 +0100 |
---|---|---|
committer | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-01-20 10:51:11 +0100 |
commit | cf9b09ff352611fb8cee3679127f3655cbe73ae7 (patch) | |
tree | 011ae091b0bff2d10a9e8dd0fd564ab2b6365f86 /src/lanes.c | |
parent | 1843a0add00186eee129b0b0a2ee605866acbb61 (diff) | |
download | lanes-cf9b09ff352611fb8cee3679127f3655cbe73ae7.tar.gz lanes-cf9b09ff352611fb8cee3679127f3655cbe73ae7.tar.bz2 lanes-cf9b09ff352611fb8cee3679127f3655cbe73ae7.zip |
get()/set() improvements
* bumped version to 3.8.0
* linda:set() accepts multiple values to set in the specified slot
* linda:get() accepts an optional count to peek several values at once
* nil values are now converted just as in send()/receive()
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/src/lanes.c b/src/lanes.c index cad8fb1..f62c39f 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -52,7 +52,7 @@ | |||
52 | * ... | 52 | * ... |
53 | */ | 53 | */ |
54 | 54 | ||
55 | char const* VERSION = "3.7.8"; | 55 | char const* VERSION = "3.8.0"; |
56 | 56 | ||
57 | /* | 57 | /* |
58 | =============================================================================== | 58 | =============================================================================== |
@@ -464,7 +464,7 @@ LUAG_FUNC( linda_send) | |||
464 | } | 464 | } |
465 | 465 | ||
466 | // convert nils to some special non-nil sentinel in sent values | 466 | // convert nils to some special non-nil sentinel in sent values |
467 | keeper_toggle_nil_sentinels( L, key_i + 1, 1); | 467 | keeper_toggle_nil_sentinels( L, key_i + 1, eLM_ToKeeper); |
468 | 468 | ||
469 | STACK_GROW( L, 1); | 469 | STACK_GROW( L, 1); |
470 | { | 470 | { |
@@ -649,7 +649,7 @@ LUAG_FUNC( linda_receive) | |||
649 | { | 649 | { |
650 | ASSERT_L( pushed >= expected_pushed_min && pushed <= expected_pushed_max); | 650 | ASSERT_L( pushed >= expected_pushed_min && pushed <= expected_pushed_max); |
651 | // replace sentinels with real nils | 651 | // replace sentinels with real nils |
652 | keeper_toggle_nil_sentinels( L, lua_gettop( L) - pushed, 0); | 652 | keeper_toggle_nil_sentinels( L, lua_gettop( L) - pushed, eLM_FromKeeper); |
653 | // To be done from within the 'K' locking area | 653 | // To be done from within the 'K' locking area |
654 | // | 654 | // |
655 | SIGNAL_ALL( &linda->read_happened); | 655 | SIGNAL_ALL( &linda->read_happened); |
@@ -725,28 +725,31 @@ LUAG_FUNC( linda_receive) | |||
725 | 725 | ||
726 | 726 | ||
727 | /* | 727 | /* |
728 | * [true] = linda_set( linda_ud, key_num|str|bool|lightuserdata [,value] ) | 728 | * [true] = linda_set( linda_ud, key_num|str|bool|lightuserdata [, value [, ...]]) |
729 | * | 729 | * |
730 | * Set a value to Linda. | 730 | * Set one or more value to Linda. |
731 | * TODO: what do we do if we set to non-nil and limit is 0? | 731 | * TODO: what do we do if we set to non-nil and limit is 0? |
732 | * | 732 | * |
733 | * Existing slot value is replaced, and possible queue entries removed. | 733 | * Existing slot value is replaced, and possible queued entries removed. |
734 | */ | 734 | */ |
735 | LUAG_FUNC( linda_set) | 735 | LUAG_FUNC( linda_set) |
736 | { | 736 | { |
737 | struct s_Linda *linda = lua_toLinda( L, 1); | 737 | struct s_Linda* const linda = lua_toLinda( L, 1); |
738 | int pushed; | 738 | int pushed; |
739 | bool_t has_value = !lua_isnil( L, 3); | 739 | bool_t has_value = lua_gettop( L) > 2; |
740 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | 740 | luaL_argcheck( L, linda, 1, "expected a linda object!"); |
741 | luaL_argcheck( L, lua_gettop( L) <= 3, 4, "too many arguments"); | ||
742 | 741 | ||
743 | // make sure the key is of a valid type | 742 | // make sure the key is of a valid type (throws an error if not the case) |
744 | check_key_types( L, 2, 2); | 743 | check_key_types( L, 2, 2); |
745 | 744 | ||
746 | { | 745 | { |
747 | struct s_Keeper* K = keeper_acquire( linda); | 746 | struct s_Keeper* K = keeper_acquire( linda); |
748 | if( K == NULL) return 0; | 747 | if( K == NULL) return 0; |
749 | // no nil->sentinel toggling, we really clear the linda contents for the given key with a set() | 748 | if( has_value) |
749 | { | ||
750 | // convert nils to some special non-nil sentinel in sent values | ||
751 | keeper_toggle_nil_sentinels( L, 3, eLM_ToKeeper); | ||
752 | } | ||
750 | pushed = keeper_call( K->L, KEEPER_API( set), L, linda, 2); | 753 | pushed = keeper_call( K->L, KEEPER_API( set), L, linda, 2); |
751 | if( pushed >= 0) // no error? | 754 | if( pushed >= 0) // no error? |
752 | { | 755 | { |
@@ -801,31 +804,32 @@ LUAG_FUNC( linda_count) | |||
801 | 804 | ||
802 | 805 | ||
803 | /* | 806 | /* |
804 | * [val]= linda_get( linda_ud, key_num|str|bool|lightuserdata ) | 807 | * [val [, ...]] = linda_get( linda_ud, key_num|str|bool|lightuserdata [, count = 1]) |
805 | * | 808 | * |
806 | * Get a value from Linda. | 809 | * Get one or more values from Linda. |
807 | * TODO: add support to get multiple values? | ||
808 | */ | 810 | */ |
809 | LUAG_FUNC( linda_get) | 811 | LUAG_FUNC( linda_get) |
810 | { | 812 | { |
811 | struct s_Linda *linda= lua_toLinda( L, 1); | 813 | struct s_Linda* const linda = lua_toLinda( L, 1); |
812 | int pushed; | 814 | int pushed; |
815 | int count = luaL_optint( L, 3, 1); | ||
816 | luaL_argcheck( L, count >= 1, 3, "count should be >= 1"); | ||
817 | luaL_argcheck( L, linda, 1, "expected a linda object"); | ||
818 | luaL_argcheck( L, lua_gettop( L) <= 3, 4, "too many arguments"); | ||
813 | 819 | ||
814 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | 820 | // make sure the key is of a valid type (throws an error if not the case) |
815 | // make sure the key is of a valid type | ||
816 | check_key_types( L, 2, 2); | 821 | check_key_types( L, 2, 2); |
817 | |||
818 | { | 822 | { |
819 | struct s_Keeper* K = keeper_acquire( linda); | 823 | struct s_Keeper* K = keeper_acquire( linda); |
820 | if( K == NULL) return 0; | 824 | if( K == NULL) return 0; |
821 | pushed = keeper_call( K->L, KEEPER_API( get), L, linda, 2); | 825 | pushed = keeper_call( K->L, KEEPER_API( get), L, linda, 2); |
822 | ASSERT_L( pushed == 0 || pushed == 1); | ||
823 | if( pushed > 0) | 826 | if( pushed > 0) |
824 | { | 827 | { |
825 | keeper_toggle_nil_sentinels( L, lua_gettop( L) - pushed, 0); | 828 | keeper_toggle_nil_sentinels( L, lua_gettop( L) - pushed, eLM_FromKeeper); |
826 | } | 829 | } |
827 | keeper_release( K); | 830 | keeper_release( K); |
828 | // must trigger error after keeper state has been released | 831 | // must trigger error after keeper state has been released |
832 | // (an error can be raised if we attempt to read an unregistered function) | ||
829 | if( pushed < 0) | 833 | if( pushed < 0) |
830 | { | 834 | { |
831 | return luaL_error( L, "tried to copy unsupported types"); | 835 | return luaL_error( L, "tried to copy unsupported types"); |