aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.c
diff options
context:
space:
mode:
authorBenoit Germain <bnt period germain arrobase gmail period com>2014-02-17 14:28:11 +0100
committerBenoit Germain <bnt period germain arrobase gmail period com>2014-02-17 14:28:11 +0100
commit5f092fe0ec8b6942c63262e7c14c7e4ba913b023 (patch)
treeba09d35bba020711d94d2c0d3fb80b0145b4d01d /src/lanes.c
parent47eb3f94373a13ac9f204ca65dfde602f53bdc1a (diff)
downloadlanes-5f092fe0ec8b6942c63262e7c14c7e4ba913b023.tar.gz
lanes-5f092fe0ec8b6942c63262e7c14c7e4ba913b023.tar.bz2
lanes-5f092fe0ec8b6942c63262e7c14c7e4ba913b023.zip
lindas can have a group for keeper state assignation control
Diffstat (limited to 'src/lanes.c')
-rw-r--r--src/lanes.c70
1 files changed, 49 insertions, 21 deletions
diff --git a/src/lanes.c b/src/lanes.c
index 597ac4b..71a9000 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -419,8 +419,10 @@ struct s_Linda
419 SIGNAL_T read_happened; 419 SIGNAL_T read_happened;
420 SIGNAL_T write_happened; 420 SIGNAL_T write_happened;
421 enum e_cancel_request simulate_cancel; 421 enum e_cancel_request simulate_cancel;
422 unsigned long group;
422 char name[1]; 423 char name[1];
423}; 424};
425#define LINDA_KEEPER_HASHSEED( linda) (linda->group ? linda->group : (unsigned long)linda)
424 426
425static void* linda_id( lua_State*, enum eDeepOp); 427static void* linda_id( lua_State*, enum eDeepOp);
426 428
@@ -489,7 +491,7 @@ LUAG_FUNC( linda_send)
489 { 491 {
490 bool_t try_again = TRUE; 492 bool_t try_again = TRUE;
491 struct s_lane* const s = get_lane_from_registry( L); 493 struct s_lane* const s = get_lane_from_registry( L);
492 struct s_Keeper* K = keeper_acquire( linda); 494 struct s_Keeper* K = keeper_acquire( LINDA_KEEPER_HASHSEED( linda));
493 lua_State* KL = K ? K->L : NULL; // need to do this for 'STACK_CHECK' 495 lua_State* KL = K ? K->L : NULL; // need to do this for 'STACK_CHECK'
494 if( KL == NULL) return 0; 496 if( KL == NULL) return 0;
495 STACK_CHECK( KL); 497 STACK_CHECK( KL);
@@ -652,7 +654,7 @@ LUAG_FUNC( linda_receive)
652 { 654 {
653 bool_t try_again = TRUE; 655 bool_t try_again = TRUE;
654 struct s_lane* const s = get_lane_from_registry( L); 656 struct s_lane* const s = get_lane_from_registry( L);
655 struct s_Keeper* K = keeper_acquire( linda); 657 struct s_Keeper* K = keeper_acquire( LINDA_KEEPER_HASHSEED( linda));
656 if( K == NULL) return 0; 658 if( K == NULL) return 0;
657 for( ;;) 659 for( ;;)
658 { 660 {
@@ -755,7 +757,7 @@ LUAG_FUNC( linda_set)
755 check_key_types( L, 2, 2); 757 check_key_types( L, 2, 2);
756 758
757 { 759 {
758 struct s_Keeper* K = keeper_acquire( linda); 760 struct s_Keeper* K = keeper_acquire( LINDA_KEEPER_HASHSEED( linda));
759 if( K == NULL) return 0; 761 if( K == NULL) return 0;
760 762
761 if( linda->simulate_cancel == CANCEL_NONE) 763 if( linda->simulate_cancel == CANCEL_NONE)
@@ -811,7 +813,7 @@ LUAG_FUNC( linda_count)
811 check_key_types( L, 2, lua_gettop( L)); 813 check_key_types( L, 2, lua_gettop( L));
812 814
813 { 815 {
814 struct s_Keeper* K = keeper_acquire( linda); 816 struct s_Keeper* K = keeper_acquire( LINDA_KEEPER_HASHSEED( linda));
815 if( K == NULL) return 0; 817 if( K == NULL) return 0;
816 pushed = keeper_call( K->L, KEEPER_API( count), L, linda, 2); 818 pushed = keeper_call( K->L, KEEPER_API( count), L, linda, 2);
817 keeper_release( K); 819 keeper_release( K);
@@ -840,7 +842,7 @@ LUAG_FUNC( linda_get)
840 // make sure the key is of a valid type (throws an error if not the case) 842 // make sure the key is of a valid type (throws an error if not the case)
841 check_key_types( L, 2, 2); 843 check_key_types( L, 2, 2);
842 { 844 {
843 struct s_Keeper* K = keeper_acquire( linda); 845 struct s_Keeper* K = keeper_acquire( LINDA_KEEPER_HASHSEED( linda));
844 if( K == NULL) return 0; 846 if( K == NULL) return 0;
845 847
846 if( linda->simulate_cancel == CANCEL_NONE) 848 if( linda->simulate_cancel == CANCEL_NONE)
@@ -890,7 +892,7 @@ LUAG_FUNC( linda_limit)
890 check_key_types( L, 2, 2); 892 check_key_types( L, 2, 2);
891 893
892 { 894 {
893 struct s_Keeper* K = keeper_acquire( linda); 895 struct s_Keeper* K = keeper_acquire( LINDA_KEEPER_HASHSEED( linda));
894 if( K == NULL) return 0; 896 if( K == NULL) return 0;
895 897
896 if( linda->simulate_cancel == CANCEL_NONE) 898 if( linda->simulate_cancel == CANCEL_NONE)
@@ -931,7 +933,7 @@ LUAG_FUNC( linda_cancel)
931 luaL_argcheck( L, lua_gettop( L) <= 2, 2, "wrong number of arguments"); 933 luaL_argcheck( L, lua_gettop( L) <= 2, 2, "wrong number of arguments");
932 934
933 // signalling must be done from inside the K locking area 935 // signalling must be done from inside the K locking area
934 K = keeper_acquire( linda); 936 K = keeper_acquire( LINDA_KEEPER_HASHSEED( linda));
935 if( K == NULL) return 0; 937 if( K == NULL) return 0;
936 938
937 linda->simulate_cancel = CANCEL_SOFT; 939 linda->simulate_cancel = CANCEL_SOFT;
@@ -1057,7 +1059,7 @@ LUAG_FUNC( linda_concat)
1057LUAG_FUNC( linda_dump) 1059LUAG_FUNC( linda_dump)
1058{ 1060{
1059 struct s_Linda* linda = lua_toLinda( L, 1); 1061 struct s_Linda* linda = lua_toLinda( L, 1);
1060 return keeper_push_linda_storage( L, linda); 1062 return keeper_push_linda_storage( L, linda, LINDA_KEEPER_HASHSEED( linda));
1061} 1063}
1062 1064
1063/* 1065/*
@@ -1093,11 +1095,28 @@ static void* linda_id( lua_State* L, enum eDeepOp op_)
1093 struct s_Linda* s; 1095 struct s_Linda* s;
1094 size_t name_len = 0; 1096 size_t name_len = 0;
1095 char const* linda_name = NULL; 1097 char const* linda_name = NULL;
1096 int const top = lua_gettop( L); 1098 unsigned long linda_group = 0;
1097 1099 // should have a string and/or a number of the stack as parameters (name and group)
1098 if( top > 0 && lua_type( L, top) == LUA_TSTRING) 1100 switch( lua_gettop( L))
1099 { 1101 {
1100 linda_name = lua_tolstring( L, top, &name_len); 1102 default: // 0
1103 break;
1104
1105 case 1: // 1 parameter, either a name or a group
1106 if( lua_type( L, -1) == LUA_TSTRING)
1107 {
1108 linda_name = lua_tolstring( L, -1, &name_len);
1109 }
1110 else
1111 {
1112 linda_group = (unsigned long) lua_tointeger( L, -1);
1113 }
1114 break;
1115
1116 case 2: // 2 parameters, a name and group, in that order
1117 linda_name = lua_tolstring( L, -2, &name_len);
1118 linda_group = lua_tointeger( L, -1);
1119 break;
1101 } 1120 }
1102 1121
1103 /* The deep data is allocated separately of Lua stack; we might no 1122 /* The deep data is allocated separately of Lua stack; we might no
@@ -1110,6 +1129,7 @@ static void* linda_id( lua_State* L, enum eDeepOp op_)
1110 SIGNAL_INIT( &s->read_happened); 1129 SIGNAL_INIT( &s->read_happened);
1111 SIGNAL_INIT( &s->write_happened); 1130 SIGNAL_INIT( &s->write_happened);
1112 s->simulate_cancel = CANCEL_NONE; 1131 s->simulate_cancel = CANCEL_NONE;
1132 s->group = linda_group << KEEPER_MAGIC_SHIFT;
1113 s->name[0] = 0; 1133 s->name[0] = 0;
1114 memcpy( s->name, linda_name, name_len ? name_len + 1 : 0); 1134 memcpy( s->name, linda_name, name_len ? name_len + 1 : 0);
1115 return s; 1135 return s;
@@ -1118,24 +1138,24 @@ static void* linda_id( lua_State* L, enum eDeepOp op_)
1118 case eDO_delete: 1138 case eDO_delete:
1119 { 1139 {
1120 struct s_Keeper* K; 1140 struct s_Keeper* K;
1121 struct s_Linda* l = lua_touserdata( L, 1); 1141 struct s_Linda* linda = lua_touserdata( L, 1);
1122 ASSERT_L( l); 1142 ASSERT_L( linda);
1123 1143
1124 /* Clean associated structures in the keeper state. 1144 /* Clean associated structures in the keeper state.
1125 */ 1145 */
1126 K = keeper_acquire( l); 1146 K = keeper_acquire( LINDA_KEEPER_HASHSEED( linda));
1127 if( K && K->L) // can be NULL if this happens during main state shutdown (lanes is GC'ed -> no keepers -> no need to cleanup) 1147 if( K && K->L) // can be NULL if this happens during main state shutdown (lanes is GC'ed -> no keepers -> no need to cleanup)
1128 { 1148 {
1129 keeper_call( K->L, KEEPER_API( clear), L, l, 0); 1149 keeper_call( K->L, KEEPER_API( clear), L, linda, 0);
1130 } 1150 }
1131 keeper_release( K); 1151 keeper_release( K);
1132 1152
1133 /* There aren't any lanes waiting on these lindas, since all proxies 1153 /* There aren't any lanes waiting on these lindas, since all proxies
1134 * have been gc'ed. Right? 1154 * have been gc'ed. Right?
1135 */ 1155 */
1136 SIGNAL_FREE( &l->read_happened); 1156 SIGNAL_FREE( &linda->read_happened);
1137 SIGNAL_FREE( &l->write_happened); 1157 SIGNAL_FREE( &linda->write_happened);
1138 free( l); 1158 free( linda);
1139 return NULL; 1159 return NULL;
1140 } 1160 }
1141 1161
@@ -1209,16 +1229,24 @@ static void* linda_id( lua_State* L, enum eDeepOp op_)
1209} 1229}
1210 1230
1211/* 1231/*
1212 * ud = lanes.linda() 1232 * ud = lanes.linda( [name[,group]])
1213 * 1233 *
1214 * returns a linda object 1234 * returns a linda object
1215 */ 1235 */
1216LUAG_FUNC( linda) 1236LUAG_FUNC( linda)
1217{ 1237{
1218 int const top = lua_gettop( L); 1238 int const top = lua_gettop( L);
1219 luaL_argcheck( L, top <= 1, top, "too many arguments"); 1239 luaL_argcheck( L, top <= 2, top, "too many arguments");
1220 if( top == 1) 1240 if( top == 1)
1241 {
1242 int const t = lua_type( L, 1);
1243 luaL_argcheck( L, t == LUA_TSTRING || t == LUA_TNUMBER, 1, "wrong parameter (should be a string or a number)");
1244 }
1245 else if( top == 2)
1246 {
1221 luaL_checktype( L, 1, LUA_TSTRING); 1247 luaL_checktype( L, 1, LUA_TSTRING);
1248 luaL_checktype( L, 2, LUA_TNUMBER);
1249 }
1222 return luaG_newdeepuserdata( L, linda_id); 1250 return luaG_newdeepuserdata( L, linda_id);
1223} 1251}
1224 1252