diff options
author | Benoit 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 |
---|---|---|
committer | Benoit 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 |
commit | 9c84074c89661cd1e776eff3d4aa5329a2ac9524 (patch) | |
tree | 3c424371c1f21f4dee493793c8316059bf8217c6 /src/lanes.c | |
parent | 32f8cdfc73ed90dcf88ffcf4bfc1a3e4d5a69e6c (diff) | |
download | lanes-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.c | 67 |
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 | ||
1405 | static int push_thread_status( lua_State* L, Lane* s) | 1398 | int 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); |