diff options
author | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-01-09 12:07:41 +0100 |
---|---|---|
committer | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-01-09 12:07:41 +0100 |
commit | cc03c619dafe39cab231045f3c8592398e4b6944 (patch) | |
tree | de471018fa75ad0255b3f986609c17af10eefcfa /src/lanes.c | |
parent | b335cbcc9f07dc71999b885ffa2962c0ec00f5eb (diff) | |
download | lanes-cc03c619dafe39cab231045f3c8592398e4b6944.tar.gz lanes-cc03c619dafe39cab231045f3c8592398e4b6944.tar.bz2 lanes-cc03c619dafe39cab231045f3c8592398e4b6944.zip |
Linda fixes
* bumped version to 3.7.7
* fix crash when calling linda:count() on unknown keys
* purge key storage with linda:set( key, nil) on an unlimited key to
reduce memory usage with lots of keys
* linda:limit() wakes write-blocked threads if necessary when the new
limit enables writes to occur again
* linda:set() wakes write-blocked threads if necessary if the operation
created some room to write into
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/src/lanes.c b/src/lanes.c index 3ccf915..d852a20 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.6"; | 55 | char const* VERSION = "3.7.7"; |
56 | 56 | ||
57 | /* | 57 | /* |
58 | =============================================================================== | 58 | =============================================================================== |
@@ -672,7 +672,7 @@ LUAG_FUNC( linda_receive) | |||
672 | 672 | ||
673 | 673 | ||
674 | /* | 674 | /* |
675 | * = linda_set( linda_ud, key_num|str|bool|lightuserdata [,value] ) | 675 | * [true] = linda_set( linda_ud, key_num|str|bool|lightuserdata [,value] ) |
676 | * | 676 | * |
677 | * Set a value to Linda. | 677 | * Set a value to Linda. |
678 | * TODO: what do we do if we set to non-nil and limit is 0? | 678 | * TODO: what do we do if we set to non-nil and limit is 0? |
@@ -682,6 +682,7 @@ LUAG_FUNC( linda_receive) | |||
682 | LUAG_FUNC( linda_set) | 682 | LUAG_FUNC( linda_set) |
683 | { | 683 | { |
684 | struct s_Linda *linda = lua_toLinda( L, 1); | 684 | struct s_Linda *linda = lua_toLinda( L, 1); |
685 | int pushed; | ||
685 | bool_t has_value = !lua_isnil( L, 3); | 686 | bool_t has_value = !lua_isnil( L, 3); |
686 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | 687 | luaL_argcheck( L, linda, 1, "expected a linda object!"); |
687 | luaL_argcheck( L, lua_gettop( L) <= 3, 4, "too many arguments"); | 688 | luaL_argcheck( L, lua_gettop( L) <= 3, 4, "too many arguments"); |
@@ -690,31 +691,31 @@ LUAG_FUNC( linda_set) | |||
690 | check_key_types( L, 2, 2); | 691 | check_key_types( L, 2, 2); |
691 | 692 | ||
692 | { | 693 | { |
693 | int pushed; | 694 | struct s_Keeper* K = keeper_acquire( linda); |
694 | struct s_Keeper *K = keeper_acquire( linda); | ||
695 | if( K == NULL) return 0; | 695 | if( K == NULL) return 0; |
696 | // no nil->sentinel toggling, we really clear the linda contents for the given key with a set() | 696 | // no nil->sentinel toggling, we really clear the linda contents for the given key with a set() |
697 | pushed = keeper_call( K->L, KEEPER_API( set), L, linda, 2); | 697 | pushed = keeper_call( K->L, KEEPER_API( set), L, linda, 2); |
698 | if( pushed >= 0) // no error? | 698 | if( pushed >= 0) // no error? |
699 | { | 699 | { |
700 | ASSERT_L( pushed == 0); | 700 | ASSERT_L( pushed == 0 || pushed == 1); |
701 | 701 | ||
702 | /* Set the signal from within 'K' locking. | ||
703 | */ | ||
704 | if( has_value) | 702 | if( has_value) |
705 | { | 703 | { |
706 | SIGNAL_ALL( &linda->write_happened); | 704 | // we put some data in the slot, tell readers that they should wake |
705 | SIGNAL_ALL( &linda->write_happened); // To be done from within the 'K' locking area | ||
706 | } | ||
707 | if( pushed == 1) | ||
708 | { | ||
709 | // the key was full, but it is no longer the case, tell writers they should wake | ||
710 | ASSERT_L( lua_type( L, -1) == LUA_TBOOLEAN && lua_toboolean( L, -1) == 1); | ||
711 | SIGNAL_ALL( &linda->read_happened); // To be done from within the 'K' locking area | ||
707 | } | 712 | } |
708 | } | 713 | } |
709 | keeper_release( K); | 714 | keeper_release( K); |
710 | // must trigger error after keeper state has been released | ||
711 | if( pushed < 0) | ||
712 | { | ||
713 | return luaL_error( L, "tried to copy unsupported types"); | ||
714 | } | ||
715 | } | 715 | } |
716 | 716 | ||
717 | return 0; | 717 | // must trigger any error after keeper state has been released |
718 | return (pushed < 0) ? luaL_error( L, "tried to copy unsupported types") : pushed; | ||
718 | } | 719 | } |
719 | 720 | ||
720 | 721 | ||
@@ -783,18 +784,20 @@ LUAG_FUNC( linda_get) | |||
783 | 784 | ||
784 | 785 | ||
785 | /* | 786 | /* |
786 | * = linda_limit( linda_ud, key_num|str|bool|lightuserdata, uint [, ...] ) | 787 | * [true] = linda_limit( linda_ud, key_num|str|bool|lightuserdata, int [, bool] ) |
787 | * | 788 | * |
788 | * Set limits to 1 or more Linda keys. | 789 | * Set limit to 1 Linda keys. |
790 | * Optionally wake threads waiting to write on the linda, in case the limit enables them to do so | ||
789 | */ | 791 | */ |
790 | LUAG_FUNC( linda_limit) | 792 | LUAG_FUNC( linda_limit) |
791 | { | 793 | { |
792 | struct s_Linda* linda= lua_toLinda( L, 1); | 794 | struct s_Linda* linda = lua_toLinda( L, 1); |
793 | int pushed; | 795 | int pushed; |
796 | bool_t wake_writers = FALSE; | ||
794 | 797 | ||
798 | // make sure we got at most 4 arguments: the linda, a key, a limit, and an optional wake-up flag. | ||
795 | luaL_argcheck( L, linda, 1, "expected a linda object!"); | 799 | luaL_argcheck( L, linda, 1, "expected a linda object!"); |
796 | // make sure we got a key and a limit | 800 | luaL_argcheck( L, lua_gettop( L) <= 4, 2, "wrong number of arguments"); |
797 | luaL_argcheck( L, lua_gettop( L) == 3, 2, "wrong number of arguments"); | ||
798 | // make sure we got a numeric limit | 801 | // make sure we got a numeric limit |
799 | luaL_checknumber( L, 3); | 802 | luaL_checknumber( L, 3); |
800 | // make sure the key is of a valid type | 803 | // make sure the key is of a valid type |
@@ -804,16 +807,16 @@ LUAG_FUNC( linda_limit) | |||
804 | struct s_Keeper* K = keeper_acquire( linda); | 807 | struct s_Keeper* K = keeper_acquire( linda); |
805 | if( K == NULL) return 0; | 808 | if( K == NULL) return 0; |
806 | pushed = keeper_call( K->L, KEEPER_API( limit), L, linda, 2); | 809 | pushed = keeper_call( K->L, KEEPER_API( limit), L, linda, 2); |
807 | ASSERT_L( pushed <= 0); // either error or no return values | 810 | ASSERT_L( pushed == 0 || pushed == 1); // no error, optional boolean value saying if we should wake blocked writer threads |
808 | keeper_release( K); | 811 | if( pushed == 1) |
809 | // must trigger error after keeper state has been released | ||
810 | if( pushed < 0) | ||
811 | { | 812 | { |
812 | return luaL_error( L, "tried to copy unsupported types"); | 813 | ASSERT_L( lua_type( L, -1) == LUA_TBOOLEAN && lua_toboolean( L, -1) == 1); |
814 | SIGNAL_ALL( &linda->read_happened); // To be done from within the 'K' locking area | ||
813 | } | 815 | } |
816 | keeper_release( K); | ||
814 | } | 817 | } |
815 | 818 | // propagate pushed boolean if any | |
816 | return 0; | 819 | return pushed; |
817 | } | 820 | } |
818 | 821 | ||
819 | 822 | ||