diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-11 15:14:52 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-11 15:14:52 +0200 |
commit | adaa36dbec1ce9aaafd61873b9d3d898a8c240cf (patch) | |
tree | 4c81e8f5983c3d696a636e2cc433ce7c0a9c3dd8 /src/lanes.c | |
parent | 1d310e6ecb6e156598337612f16573d9cd284f5e (diff) | |
download | lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.tar.gz lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.tar.bz2 lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.zip |
Bring all interesting fixes from the C++ implementation back into the C implementation
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 115 |
1 files changed, 60 insertions, 55 deletions
diff --git a/src/lanes.c b/src/lanes.c index 332a1b8..ca2b53a 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -442,7 +442,7 @@ static bool_t selfdestruct_remove( Lane* s) | |||
442 | /* | 442 | /* |
443 | * Process end; cancel any still free-running threads | 443 | * Process end; cancel any still free-running threads |
444 | */ | 444 | */ |
445 | static int selfdestruct_gc( lua_State* L) | 445 | static int universe_gc( lua_State* L) |
446 | { | 446 | { |
447 | Universe* U = (Universe*) lua_touserdata( L, 1); | 447 | Universe* U = (Universe*) lua_touserdata( L, 1); |
448 | 448 | ||
@@ -456,7 +456,7 @@ static int selfdestruct_gc( lua_State* L) | |||
456 | while( s != SELFDESTRUCT_END) | 456 | while( s != SELFDESTRUCT_END) |
457 | { | 457 | { |
458 | // attempt a regular unforced hard cancel with a small timeout | 458 | // attempt a regular unforced hard cancel with a small timeout |
459 | bool_t cancelled = THREAD_ISNULL( s->thread) || thread_cancel( L, s, CO_Hard, 0.0001, FALSE, 0.0); | 459 | bool_t cancelled = THREAD_ISNULL( s->thread) || (thread_cancel( L, s, CO_Hard, 0.0001, FALSE, 0.0) != CR_Timeout); |
460 | // if we failed, and we know the thread is waiting on a linda | 460 | // if we failed, and we know the thread is waiting on a linda |
461 | if( cancelled == FALSE && s->status == WAITING && s->waiting_on != NULL) | 461 | if( cancelled == FALSE && s->status == WAITING && s->waiting_on != NULL) |
462 | { | 462 | { |
@@ -609,7 +609,7 @@ static int selfdestruct_gc( lua_State* L) | |||
609 | // | 609 | // |
610 | LUAG_FUNC( set_singlethreaded) | 610 | LUAG_FUNC( set_singlethreaded) |
611 | { | 611 | { |
612 | uint_t cores = luaG_optunsigned( L, 1, 1); | 612 | lua_Integer cores = luaG_optunsigned( L, 1, 1); |
613 | (void) cores; // prevent "unused" warning | 613 | (void) cores; // prevent "unused" warning |
614 | 614 | ||
615 | #ifdef PLATFORM_OSX | 615 | #ifdef PLATFORM_OSX |
@@ -653,24 +653,16 @@ static DECLARE_CONST_UNIQUE_KEY( EXTENDED_STACKTRACE_REGKEY, 0x2357c69a7c92c936) | |||
653 | 653 | ||
654 | LUAG_FUNC( set_error_reporting) | 654 | LUAG_FUNC( set_error_reporting) |
655 | { | 655 | { |
656 | bool_t equal; | 656 | luaL_checktype(L, 1, LUA_TSTRING); |
657 | luaL_checktype( L, 1, LUA_TSTRING); | 657 | char const* mode = lua_tostring(L, 1); |
658 | lua_pushliteral( L, "extended"); | 658 | bool_t const extended = (strcmp(mode, "extended") == 0); |
659 | equal = lua_rawequal( L, -1, 1); | 659 | bool_t const basic = (strcmp(mode, "basic") == 0); |
660 | lua_pop( L, 1); | 660 | if (!extended && !basic) |
661 | if( equal) | ||
662 | { | 661 | { |
663 | goto done; | 662 | return luaL_error(L, "unsupported error reporting model %s", mode); |
664 | } | 663 | } |
665 | lua_pushliteral( L, "basic"); | 664 | |
666 | equal = !lua_rawequal( L, -1, 1); | 665 | REGISTRY_SET( L, EXTENDED_STACKTRACE_REGKEY, lua_pushboolean( L, extended ? 1 : 0)); |
667 | lua_pop( L, 1); | ||
668 | if( equal) | ||
669 | { | ||
670 | return luaL_error( L, "unsupported error reporting model"); | ||
671 | } | ||
672 | done: | ||
673 | REGISTRY_SET( L, EXTENDED_STACKTRACE_REGKEY, lua_pushboolean( L, equal)); | ||
674 | return 0; | 666 | return 0; |
675 | } | 667 | } |
676 | 668 | ||
@@ -788,7 +780,8 @@ static void push_stack_trace( lua_State* L, int rc_, int stk_base_) | |||
788 | 780 | ||
789 | LUAG_FUNC( set_debug_threadname) | 781 | LUAG_FUNC( set_debug_threadname) |
790 | { | 782 | { |
791 | DECLARE_CONST_UNIQUE_KEY( hidden_regkey, LG_set_debug_threadname); | 783 | // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator |
784 | static DECLARE_CONST_UNIQUE_KEY( hidden_regkey, 0x79C0669AAAE04440); | ||
792 | // C s_lane structure is a light userdata upvalue | 785 | // C s_lane structure is a light userdata upvalue |
793 | Lane* s = lua_touserdata( L, lua_upvalueindex( 1)); | 786 | Lane* s = lua_touserdata( L, lua_upvalueindex( 1)); |
794 | luaL_checktype( L, -1, LUA_TSTRING); // "name" | 787 | luaL_checktype( L, -1, LUA_TSTRING); // "name" |
@@ -1049,10 +1042,10 @@ LUAG_FUNC( lane_new) | |||
1049 | char const* libs_str = lua_tostring( L, 2); | 1042 | char const* libs_str = lua_tostring( L, 2); |
1050 | bool_t const have_priority = !lua_isnoneornil( L, 3); | 1043 | bool_t const have_priority = !lua_isnoneornil( L, 3); |
1051 | int const priority = have_priority ? (int) lua_tointeger( L, 3) : THREAD_PRIO_DEFAULT; | 1044 | int const priority = have_priority ? (int) lua_tointeger( L, 3) : THREAD_PRIO_DEFAULT; |
1052 | uint_t const globals_idx = lua_isnoneornil( L, 4) ? 0 : 4; | 1045 | int const globals_idx = lua_isnoneornil( L, 4) ? 0 : 4; |
1053 | uint_t const package_idx = lua_isnoneornil( L, 5) ? 0 : 5; | 1046 | int const package_idx = lua_isnoneornil( L, 5) ? 0 : 5; |
1054 | uint_t const required_idx = lua_isnoneornil( L, 6) ? 0 : 6; | 1047 | int const required_idx = lua_isnoneornil( L, 6) ? 0 : 6; |
1055 | uint_t const gc_cb_idx = lua_isnoneornil( L, 7) ? 0 : 7; | 1048 | int const gc_cb_idx = lua_isnoneornil( L, 7) ? 0 : 7; |
1056 | 1049 | ||
1057 | #define FIXED_ARGS 7 | 1050 | #define FIXED_ARGS 7 |
1058 | int const nargs = lua_gettop(L) - FIXED_ARGS; | 1051 | int const nargs = lua_gettop(L) - FIXED_ARGS; |
@@ -1090,7 +1083,8 @@ LUAG_FUNC( lane_new) | |||
1090 | if( package_idx != 0) | 1083 | if( package_idx != 0) |
1091 | { | 1084 | { |
1092 | // when copying with mode eLM_LaneBody, should raise an error in case of problem, not leave it one the stack | 1085 | // when copying with mode eLM_LaneBody, should raise an error in case of problem, not leave it one the stack |
1093 | (void) luaG_inter_copy_package( U, L, L2, package_idx, eLM_LaneBody); | 1086 | InterCopyResult const ret = luaG_inter_copy_package( U, L, L2, package_idx, eLM_LaneBody); |
1087 | ASSERT_L(ret == eICR_Success); // either all went well, or we should not even get here | ||
1094 | } | 1088 | } |
1095 | 1089 | ||
1096 | // modules to require in the target lane *before* the function is transfered! | 1090 | // modules to require in the target lane *before* the function is transfered! |
@@ -1179,25 +1173,32 @@ LUAG_FUNC( lane_new) | |||
1179 | STACK_MID( L2, 0); | 1173 | STACK_MID( L2, 0); |
1180 | 1174 | ||
1181 | // Lane main function | 1175 | // Lane main function |
1182 | if( lua_type( L, 1) == LUA_TFUNCTION) | ||
1183 | { | 1176 | { |
1184 | int res; | 1177 | int const func_type = lua_type(L, 1); |
1185 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); | 1178 | if (func_type == LUA_TFUNCTION) |
1186 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | ||
1187 | lua_pushvalue( L, 1); // func libs priority globals package required gc_cb [... args ...] func | ||
1188 | res = luaG_inter_move( U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func | ||
1189 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | ||
1190 | if( res != 0) | ||
1191 | { | 1179 | { |
1192 | return luaL_error( L, "tried to copy unsupported types"); | 1180 | InterCopyResult res; |
1181 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END)); | ||
1182 | DEBUGSPEW_CODE(++U->debugspew_indent_depth); | ||
1183 | lua_pushvalue(L, 1); // func libs priority globals package required gc_cb [... args ...] func | ||
1184 | res = luaG_inter_move(U, L, L2, 1, eLM_LaneBody); // func libs priority globals package required gc_cb [... args ...] // func | ||
1185 | DEBUGSPEW_CODE(--U->debugspew_indent_depth); | ||
1186 | if (res != eICR_Success) | ||
1187 | { | ||
1188 | return luaL_error(L, "tried to copy unsupported types"); | ||
1189 | } | ||
1193 | } | 1190 | } |
1194 | } | 1191 | else if (func_type == LUA_TSTRING) |
1195 | else if( lua_type( L, 1) == LUA_TSTRING) | ||
1196 | { | ||
1197 | // compile the string | ||
1198 | if( luaL_loadstring( L2, lua_tostring( L, 1)) != 0) // func | ||
1199 | { | 1192 | { |
1200 | return luaL_error( L, "error when parsing lane function code"); | 1193 | // compile the string |
1194 | if (luaL_loadstring(L2, lua_tostring(L, 1)) != 0) // func | ||
1195 | { | ||
1196 | return luaL_error(L, "error when parsing lane function code"); | ||
1197 | } | ||
1198 | } | ||
1199 | else | ||
1200 | { | ||
1201 | luaL_error(L, "Expected function, got %s", lua_typename(L, func_type)); // doesn't return | ||
1201 | } | 1202 | } |
1202 | } | 1203 | } |
1203 | STACK_MID( L, 0); | 1204 | STACK_MID( L, 0); |
@@ -1207,12 +1208,12 @@ LUAG_FUNC( lane_new) | |||
1207 | // revive arguments | 1208 | // revive arguments |
1208 | if( nargs > 0) | 1209 | if( nargs > 0) |
1209 | { | 1210 | { |
1210 | int res; | 1211 | InterCopyResult res; |
1211 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); | 1212 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END)); |
1212 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1213 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1213 | res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...] | 1214 | res = luaG_inter_move( U, L, L2, nargs, eLM_LaneBody); // func libs priority globals package required gc_cb // func [... args ...] |
1214 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1215 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
1215 | if( res != 0) | 1216 | if( res != eICR_Success) |
1216 | { | 1217 | { |
1217 | return luaL_error( L, "tried to copy unsupported types"); | 1218 | return luaL_error( L, "tried to copy unsupported types"); |
1218 | } | 1219 | } |
@@ -1277,7 +1278,7 @@ LUAG_FUNC( lane_new) | |||
1277 | lua_setiuservalue( L, -2, 1); // func libs priority globals package required gc_cb lane | 1278 | lua_setiuservalue( L, -2, 1); // func libs priority globals package required gc_cb lane |
1278 | 1279 | ||
1279 | // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). | 1280 | // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). |
1280 | REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...] | 1281 | REGISTRY_SET( L2, LANE_POINTER_REGKEY, lua_pushlightuserdata( L2, s)); // func [... args ...] |
1281 | 1282 | ||
1282 | STACK_END( L, 1); | 1283 | STACK_END( L, 1); |
1283 | STACK_END( L2, 1 + nargs); | 1284 | STACK_END( L2, 1 + nargs); |
@@ -1457,8 +1458,8 @@ LUAG_FUNC( thread_join) | |||
1457 | { | 1458 | { |
1458 | case DONE: | 1459 | case DONE: |
1459 | { | 1460 | { |
1460 | uint_t n = lua_gettop( L2); // whole L2 stack | 1461 | int n = lua_gettop( L2); // whole L2 stack |
1461 | if( (n > 0) && (luaG_inter_move( U, L2, L, n, eLM_LaneBody) != 0)) | 1462 | if( (n > 0) && (luaG_inter_move( U, L2, L, n, eLM_LaneBody) != eICR_Success)) |
1462 | { | 1463 | { |
1463 | return luaL_error( L, "tried to copy unsupported types"); | 1464 | return luaL_error( L, "tried to copy unsupported types"); |
1464 | } | 1465 | } |
@@ -1472,7 +1473,7 @@ LUAG_FUNC( thread_join) | |||
1472 | STACK_GROW( L, 3); | 1473 | STACK_GROW( L, 3); |
1473 | lua_pushnil( L); | 1474 | lua_pushnil( L); |
1474 | // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ... | 1475 | // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ... |
1475 | if( luaG_inter_move( U, L2, L, n, eLM_LaneBody) != 0) // nil "err" [trace] | 1476 | if( luaG_inter_move( U, L2, L, n, eLM_LaneBody) != eICR_Success) // nil "err" [trace] |
1476 | { | 1477 | { |
1477 | return luaL_error( L, "tried to copy unsupported types: %s", lua_tostring( L, -n)); | 1478 | return luaL_error( L, "tried to copy unsupported types: %s", lua_tostring( L, -n)); |
1478 | } | 1479 | } |
@@ -1874,7 +1875,7 @@ LUAG_FUNC( configure) | |||
1874 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1875 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1875 | lua_newtable( L); // settings universe mt | 1876 | lua_newtable( L); // settings universe mt |
1876 | lua_getfield( L, 1, "shutdown_timeout"); // settings universe mt shutdown_timeout | 1877 | lua_getfield( L, 1, "shutdown_timeout"); // settings universe mt shutdown_timeout |
1877 | lua_pushcclosure( L, selfdestruct_gc, 1); // settings universe mt selfdestruct_gc | 1878 | lua_pushcclosure( L, universe_gc, 1); // settings universe mt universe_gc |
1878 | lua_setfield( L, -2, "__gc"); // settings universe mt | 1879 | lua_setfield( L, -2, "__gc"); // settings universe mt |
1879 | lua_setmetatable( L, -2); // settings universe | 1880 | lua_setmetatable( L, -2); // settings universe |
1880 | lua_pop( L, 1); // settings | 1881 | lua_pop( L, 1); // settings |
@@ -2051,16 +2052,20 @@ static void EnableCrashingOnCrashes( void) | |||
2051 | const DWORD EXCEPTION_SWALLOWING = 0x1; | 2052 | const DWORD EXCEPTION_SWALLOWING = 0x1; |
2052 | 2053 | ||
2053 | HMODULE kernel32 = LoadLibraryA("kernel32.dll"); | 2054 | HMODULE kernel32 = LoadLibraryA("kernel32.dll"); |
2054 | tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy"); | 2055 | if (kernel32) |
2055 | tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy"); | ||
2056 | if( pGetPolicy && pSetPolicy) | ||
2057 | { | 2056 | { |
2058 | DWORD dwFlags; | 2057 | tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy"); |
2059 | if( pGetPolicy( &dwFlags)) | 2058 | tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy"); |
2059 | if( pGetPolicy && pSetPolicy) | ||
2060 | { | 2060 | { |
2061 | // Turn off the filter | 2061 | DWORD dwFlags; |
2062 | pSetPolicy( dwFlags & ~EXCEPTION_SWALLOWING); | 2062 | if( pGetPolicy( &dwFlags)) |
2063 | { | ||
2064 | // Turn off the filter | ||
2065 | pSetPolicy( dwFlags & ~EXCEPTION_SWALLOWING); | ||
2066 | } | ||
2063 | } | 2067 | } |
2068 | FreeLibrary(kernel32); | ||
2064 | } | 2069 | } |
2065 | //typedef void (* SignalHandlerPointer)( int); | 2070 | //typedef void (* SignalHandlerPointer)( int); |
2066 | /*SignalHandlerPointer previousHandler =*/ signal( SIGABRT, signal_handler); | 2071 | /*SignalHandlerPointer previousHandler =*/ signal( SIGABRT, signal_handler); |
@@ -2072,7 +2077,7 @@ static void EnableCrashingOnCrashes( void) | |||
2072 | while( !s_ecoc_go_ahead) { Sleep(1); } // changes threads | 2077 | while( !s_ecoc_go_ahead) { Sleep(1); } // changes threads |
2073 | } | 2078 | } |
2074 | } | 2079 | } |
2075 | #endif // PLATFORM_WIN32 | 2080 | #endif // PLATFORM_WIN32 && !defined NDEBUG |
2076 | 2081 | ||
2077 | int LANES_API luaopen_lanes_core( lua_State* L) | 2082 | int LANES_API luaopen_lanes_core( lua_State* L) |
2078 | { | 2083 | { |