diff options
author | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-02-17 14:28:11 +0100 |
---|---|---|
committer | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-02-17 14:28:11 +0100 |
commit | 5f092fe0ec8b6942c63262e7c14c7e4ba913b023 (patch) | |
tree | ba09d35bba020711d94d2c0d3fb80b0145b4d01d /src/lanes.c | |
parent | 47eb3f94373a13ac9f204ca65dfde602f53bdc1a (diff) | |
download | lanes-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.c | 70 |
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 | ||
425 | static void* linda_id( lua_State*, enum eDeepOp); | 427 | static 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) | |||
1057 | LUAG_FUNC( linda_dump) | 1059 | LUAG_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 | */ |
1216 | LUAG_FUNC( linda) | 1236 | LUAG_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 | ||