aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.c
diff options
context:
space:
mode:
authorBenoit Germain <bnt period germain arrobase gmail period com>2014-01-09 12:07:41 +0100
committerBenoit Germain <bnt period germain arrobase gmail period com>2014-01-09 12:07:41 +0100
commitcc03c619dafe39cab231045f3c8592398e4b6944 (patch)
treede471018fa75ad0255b3f986609c17af10eefcfa /src/lanes.c
parentb335cbcc9f07dc71999b885ffa2962c0ec00f5eb (diff)
downloadlanes-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.c55
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
55char const* VERSION = "3.7.6"; 55char 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)
682LUAG_FUNC( linda_set) 682LUAG_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*/
790LUAG_FUNC( linda_limit) 792LUAG_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