aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.c
diff options
context:
space:
mode:
authorBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2019-04-26 12:20:06 +0200
committerBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2019-04-26 12:20:06 +0200
commit9c84074c89661cd1e776eff3d4aa5329a2ac9524 (patch)
tree3c424371c1f21f4dee493793c8316059bf8217c6 /src/lanes.c
parent32f8cdfc73ed90dcf88ffcf4bfc1a3e4d5a69e6c (diff)
downloadlanes-9c84074c89661cd1e776eff3d4aa5329a2ac9524.tar.gz
lanes-9c84074c89661cd1e776eff3d4aa5329a2ac9524.tar.bz2
lanes-9c84074c89661cd1e776eff3d4aa5329a2ac9524.zip
Lane cancellation rework
opt.cancelstep is gone, hook is installed by lane:cancel() if requested lane:cancel() rework (see doc)
Diffstat (limited to 'src/lanes.c')
-rw-r--r--src/lanes.c67
1 files changed, 30 insertions, 37 deletions
diff --git a/src/lanes.c b/src/lanes.c
index cbac6da..8f159a9 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -452,7 +452,7 @@ static int selfdestruct_gc( lua_State* L)
452 while( s != SELFDESTRUCT_END) 452 while( s != SELFDESTRUCT_END)
453 { 453 {
454 // attempt a regular unforced hard cancel with a small timeout 454 // attempt a regular unforced hard cancel with a small timeout
455 bool_t cancelled = THREAD_ISNULL( s->thread) || thread_cancel( L, s, 0.0001, FALSE, 0.0); 455 bool_t cancelled = THREAD_ISNULL( s->thread) || thread_cancel( L, s, CO_Hard, 0.0001, FALSE, 0.0);
456 // if we failed, and we know the thread is waiting on a linda 456 // if we failed, and we know the thread is waiting on a linda
457 if( cancelled == FALSE && s->status == WAITING && s->waiting_on != NULL) 457 if( cancelled == FALSE && s->status == WAITING && s->waiting_on != NULL)
458 { 458 {
@@ -1027,7 +1027,6 @@ static DECLARE_CONST_UNIQUE_KEY( GCCB_KEY, 0xcfb1f046ef074e88);
1027//--- 1027//---
1028// lane_ud = lane_new( function 1028// lane_ud = lane_new( function
1029// , [libs_str] 1029// , [libs_str]
1030// , [cancelstep_uint=0]
1031// , [priority_int=0] 1030// , [priority_int=0]
1032// , [globals_tbl] 1031// , [globals_tbl]
1033// , [package_tbl] 1032// , [package_tbl]
@@ -1044,14 +1043,13 @@ LUAG_FUNC( lane_new)
1044 Lane** ud; 1043 Lane** ud;
1045 1044
1046 char const* libs_str = lua_tostring( L, 2); 1045 char const* libs_str = lua_tostring( L, 2);
1047 uint_t cancelstep_idx = luaG_optunsigned( L, 3, 0); 1046 int const priority = (int) luaL_optinteger( L, 3, 0);
1048 int const priority = (int) luaL_optinteger( L, 4, 0); 1047 uint_t globals_idx = lua_isnoneornil( L, 4) ? 0 : 4;
1049 uint_t globals_idx = lua_isnoneornil( L, 5) ? 0 : 5; 1048 uint_t package_idx = lua_isnoneornil( L, 5) ? 0 : 5;
1050 uint_t package_idx = lua_isnoneornil( L, 6) ? 0 : 6; 1049 uint_t required_idx = lua_isnoneornil( L, 6) ? 0 : 6;
1051 uint_t required_idx = lua_isnoneornil( L, 7) ? 0 : 7; 1050 uint_t gc_cb_idx = lua_isnoneornil( L, 7) ? 0 : 7;
1052 uint_t gc_cb_idx = lua_isnoneornil( L, 8) ? 0 : 8; 1051
1053 1052#define FIXED_ARGS 7
1054#define FIXED_ARGS 8
1055 int const nargs = lua_gettop(L) - FIXED_ARGS; 1053 int const nargs = lua_gettop(L) - FIXED_ARGS;
1056 Universe* U = universe_get( L); 1054 Universe* U = universe_get( L);
1057 ASSERT_L( nargs >= 0); 1055 ASSERT_L( nargs >= 0);
@@ -1074,7 +1072,7 @@ LUAG_FUNC( lane_new)
1074 STACK_GROW( L2, nargs + 3); // 1072 STACK_GROW( L2, nargs + 3); //
1075 STACK_CHECK( L2, 0); 1073 STACK_CHECK( L2, 0);
1076 1074
1077 STACK_GROW( L, 3); // func libs cancelstep priority globals package required gc_cb [... args ...] 1075 STACK_GROW( L, 3); // func libs priority globals package required gc_cb [... args ...]
1078 STACK_CHECK( L, 0); 1076 STACK_CHECK( L, 0);
1079 1077
1080 // give a default "Lua" name to the thread to see VM name in Decoda debugger 1078 // give a default "Lua" name to the thread to see VM name in Decoda debugger
@@ -1103,8 +1101,8 @@ LUAG_FUNC( lane_new)
1103 return luaL_error( L, "expected required module list as a table, got %s", luaL_typename( L, required_idx)); 1101 return luaL_error( L, "expected required module list as a table, got %s", luaL_typename( L, required_idx));
1104 } 1102 }
1105 1103
1106 lua_pushnil( L); // func libs cancelstep priority globals package required gc_cb [... args ...] nil 1104 lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil
1107 while( lua_next( L, required_idx) != 0) // func libs cancelstep priority globals package required gc_cb [... args ...] n "modname" 1105 while( lua_next( L, required_idx) != 0) // func libs priority globals package required gc_cb [... args ...] n "modname"
1108 { 1106 {
1109 if( lua_type( L, -1) != LUA_TSTRING || lua_type( L, -2) != LUA_TNUMBER || lua_tonumber( L, -2) != nbRequired) 1107 if( lua_type( L, -1) != LUA_TSTRING || lua_type( L, -2) != LUA_TNUMBER || lua_tonumber( L, -2) != nbRequired)
1110 { 1108 {
@@ -1130,7 +1128,7 @@ LUAG_FUNC( lane_new)
1130 if( lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode 1128 if( lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode
1131 { 1129 {
1132 // propagate error to main state if any 1130 // propagate error to main state if any
1133 luaG_inter_move( U, L2, L, 1, eLM_LaneBody); // func libs cancelstep priority globals package required gc_cb [... args ...] n "modname" error 1131 luaG_inter_move( U, L2, L, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] n "modname" error
1134 return lua_error( L); 1132 return lua_error( L);
1135 } 1133 }
1136 // after requiring the module, register the functions it exported in our name<->function database 1134 // after requiring the module, register the functions it exported in our name<->function database
@@ -1138,9 +1136,9 @@ LUAG_FUNC( lane_new)
1138 lua_pop( L2, 1); // 1136 lua_pop( L2, 1); //
1139 } 1137 }
1140 } 1138 }
1141 lua_pop( L, 1); // func libs cancelstep priority globals package required gc_cb [... args ...] n 1139 lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] n
1142 ++ nbRequired; 1140 ++ nbRequired;
1143 } // func libs cancelstep priority globals package required gc_cb [... args ...] 1141 } // func libs priority globals package required gc_cb [... args ...]
1144 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1142 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1145 } 1143 }
1146 STACK_MID( L, 0); 1144 STACK_MID( L, 0);
@@ -1158,16 +1156,16 @@ LUAG_FUNC( lane_new)
1158 } 1156 }
1159 1157
1160 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1158 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1161 lua_pushnil( L); // func libs cancelstep priority globals package required gc_cb [... args ...] nil 1159 lua_pushnil( L); // func libs priority globals package required gc_cb [... args ...] nil
1162 // Lua 5.2 wants us to push the globals table on the stack 1160 // Lua 5.2 wants us to push the globals table on the stack
1163 lua_pushglobaltable( L2); // _G 1161 lua_pushglobaltable( L2); // _G
1164 while( lua_next( L, globals_idx)) // func libs cancelstep priority globals package required gc_cb [... args ...] k v 1162 while( lua_next( L, globals_idx)) // func libs priority globals package required gc_cb [... args ...] k v
1165 { 1163 {
1166 luaG_inter_copy( U, L, L2, 2, eLM_LaneBody); // _G k v 1164 luaG_inter_copy( U, L, L2, 2, eLM_LaneBody); // _G k v
1167 // assign it in L2's globals table 1165 // assign it in L2's globals table
1168 lua_rawset( L2, -3); // _G 1166 lua_rawset( L2, -3); // _G
1169 lua_pop( L, 1); // func libs cancelstep priority globals package required gc_cb [... args ...] k 1167 lua_pop( L, 1); // func libs priority globals package required gc_cb [... args ...] k
1170 } // func libs cancelstep priority globals package required gc_cb [... args ...] 1168 } // func libs priority globals package required gc_cb [... args ...]
1171 lua_pop( L2, 1); // 1169 lua_pop( L2, 1); //
1172 1170
1173 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1171 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
@@ -1181,8 +1179,8 @@ LUAG_FUNC( lane_new)
1181 int res; 1179 int res;
1182 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); 1180 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END));
1183 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1181 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1184 lua_pushvalue( L, 1); // func libs cancelstep priority globals package required gc_cb [... args ...] func 1182 lua_pushvalue( L, 1); // func libs priority globals package required gc_cb [... args ...] func
1185 res = luaG_inter_move( U, L, L2, 1, eLM_LaneBody); // func libs cancelstep priority globals package required gc_cb [... args ...] // func 1183 res = luaG_inter_move( U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func
1186 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1184 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1187 if( res != 0) 1185 if( res != 0)
1188 { 1186 {
@@ -1207,7 +1205,7 @@ LUAG_FUNC( lane_new)
1207 int res; 1205 int res;
1208 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); 1206 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END));
1209 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1207 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1210 res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs cancelstep priority globals package required gc_cb // func [... args ...] 1208 res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...]
1211 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1209 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1212 if( res != 0) 1210 if( res != 0)
1213 { 1211 {
@@ -1222,7 +1220,7 @@ LUAG_FUNC( lane_new)
1222 // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) 1220 // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread)
1223 // 1221 //
1224 // a Lane full userdata needs a single uservalue 1222 // a Lane full userdata needs a single uservalue
1225 ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs cancelstep priority globals package required gc_cb lane 1223 ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs priority globals package required gc_cb lane
1226 s = *ud = (Lane*) malloc( sizeof( Lane)); 1224 s = *ud = (Lane*) malloc( sizeof( Lane));
1227 if( s == NULL) 1225 if( s == NULL)
1228 { 1226 {
@@ -1252,8 +1250,8 @@ LUAG_FUNC( lane_new)
1252 1250
1253 // Set metatable for the userdata 1251 // Set metatable for the userdata
1254 // 1252 //
1255 lua_pushvalue( L, lua_upvalueindex( 1)); // func libs cancelstep priority globals package required gc_cb lane mt 1253 lua_pushvalue( L, lua_upvalueindex( 1)); // func libs priority globals package required gc_cb lane mt
1256 lua_setmetatable( L, -2); // func libs cancelstep priority globals package required gc_cb lane 1254 lua_setmetatable( L, -2); // func libs priority globals package required gc_cb lane
1257 STACK_MID( L, 1); 1255 STACK_MID( L, 1);
1258 1256
1259 // Create uservalue for the userdata 1257 // Create uservalue for the userdata
@@ -1263,21 +1261,16 @@ LUAG_FUNC( lane_new)
1263 // Store the gc_cb callback in the uservalue 1261 // Store the gc_cb callback in the uservalue
1264 if( gc_cb_idx > 0) 1262 if( gc_cb_idx > 0)
1265 { 1263 {
1266 push_unique_key( L, GCCB_KEY); // func libs cancelstep priority globals package required gc_cb lane uv k 1264 push_unique_key( L, GCCB_KEY); // func libs priority globals package required gc_cb lane uv k
1267 lua_pushvalue( L, gc_cb_idx); // func libs cancelstep priority globals package required gc_cb lane uv k gc_cb 1265 lua_pushvalue( L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb
1268 lua_rawset( L, -3); // func libs cancelstep priority globals package required gc_cb lane uv 1266 lua_rawset( L, -3); // func libs priority globals package required gc_cb lane uv
1269 } 1267 }
1270 1268
1271 lua_setiuservalue( L, -2, 1); // func libs cancelstep priority globals package required gc_cb lane 1269 lua_setiuservalue( L, -2, 1); // func libs priority globals package required gc_cb lane
1272 1270
1273 // Store 's' in the lane's registry, for 'cancel_test()' (even if 'cs'==0 we still do cancel tests at pending send/receive). 1271 // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive).
1274 REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...] 1272 REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...]
1275 1273
1276 if( cancelstep_idx)
1277 {
1278 lua_sethook( L2, cancel_hook, LUA_MASKCOUNT, cancelstep_idx);
1279 }
1280
1281 STACK_END( L, 1); 1274 STACK_END( L, 1);
1282 STACK_END( L2, 1 + nargs); 1275 STACK_END( L2, 1 + nargs);
1283 1276
@@ -1402,7 +1395,7 @@ static char const * thread_status_string( Lane* s)
1402 return str; 1395 return str;
1403} 1396}
1404 1397
1405static int push_thread_status( lua_State* L, Lane* s) 1398int push_thread_status( lua_State* L, Lane* s)
1406{ 1399{
1407 char const* const str = thread_status_string( s); 1400 char const* const str = thread_status_string( s);
1408 ASSERT_L( str); 1401 ASSERT_L( str);