aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r--src/lanes.cpp71
1 files changed, 32 insertions, 39 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index 86972f7..327c2df 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -1,6 +1,6 @@
1/* 1/*
2 * LANES.C Copyright (c) 2007-08, Asko Kauppi 2 * LANES.CPP Copyright (c) 2007-08, Asko Kauppi
3 * Copyright (C) 2009-19, Benoit Germain 3 * Copyright (C) 2009-24, Benoit Germain
4 * 4 *
5 * Multithreading in Lua. 5 * Multithreading in Lua.
6 * 6 *
@@ -56,7 +56,7 @@
56=============================================================================== 56===============================================================================
57 57
58Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> 58Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com>
59 2011-19 Benoit Germain <bnt.germain@gmail.com> 59 2011-24 Benoit Germain <bnt.germain@gmail.com>
60 60
61Permission is hereby granted, free of charge, to any person obtaining a copy 61Permission is hereby granted, free of charge, to any person obtaining a copy
62of this software and associated documentation files (the "Software"), to deal 62of this software and associated documentation files (the "Software"), to deal
@@ -79,22 +79,17 @@ THE SOFTWARE.
79=============================================================================== 79===============================================================================
80*/ 80*/
81 81
82#include <string.h>
83#include <stdio.h>
84#include <stdlib.h>
85#include <ctype.h>
86#include <assert.h>
87
88#include "lanes.h" 82#include "lanes.h"
89#include "threading.h" 83
90#include "compat.h" 84#include "compat.h"
91#include "tools.h"
92#include "state.h"
93#include "universe.h"
94#include "keeper.h" 85#include "keeper.h"
95#include "lanes_private.h" 86#include "lanes_private.h"
87#include "state.h"
88#include "threading.h"
89#include "tools.h"
90#include "universe.h"
96 91
97#if !(defined( PLATFORM_XBOX) || defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)) 92#if !(defined(PLATFORM_XBOX) || defined(PLATFORM_WIN32) || defined(PLATFORM_POCKETPC))
98# include <sys/time.h> 93# include <sys/time.h>
99#endif 94#endif
100 95
@@ -157,8 +152,8 @@ static bool push_registry_table( lua_State* L, UniqueKey key, bool create)
157 STACK_GROW(L, 3); 152 STACK_GROW(L, 3);
158 STACK_CHECK_START_REL(L, 0); 153 STACK_CHECK_START_REL(L, 0);
159 154
160 key.query_registry(L); // ? 155 key.pushValue(L); // ?
161 if (lua_isnil(L, -1)) // nil? 156 if (lua_isnil(L, -1)) // nil?
162 { 157 {
163 lua_pop(L, 1); // 158 lua_pop(L, 1); //
164 STACK_CHECK(L, 0); 159 STACK_CHECK(L, 0);
@@ -168,8 +163,8 @@ static bool push_registry_table( lua_State* L, UniqueKey key, bool create)
168 return false; 163 return false;
169 } 164 }
170 165
171 lua_newtable( L); // t 166 lua_newtable(L); // t
172 key.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); 167 key.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); });
173 } 168 }
174 STACK_CHECK(L, 1); 169 STACK_CHECK(L, 1);
175 return true; // table pushed 170 return true; // table pushed
@@ -653,14 +648,14 @@ LUAG_FUNC( set_error_reporting)
653 return luaL_error(L, "unsupported error reporting model"); 648 return luaL_error(L, "unsupported error reporting model");
654 } 649 }
655done: 650done:
656 EXTENDED_STACKTRACE_REGKEY.set_registry(L, [equal](lua_State* L) { lua_pushboolean(L, equal); }); 651 EXTENDED_STACKTRACE_REGKEY.setValue(L, [equal](lua_State* L) { lua_pushboolean(L, equal); });
657 return 0; 652 return 0;
658} 653}
659 654
660static int lane_error( lua_State* L) 655static int lane_error(lua_State* L)
661{ 656{
662 // error message (any type) 657 // error message (any type)
663 STACK_CHECK_START_ABS(L, 1); // some_error 658 STACK_CHECK_START_ABS(L, 1); // some_error
664 659
665 // Don't do stack survey for cancelled lanes. 660 // Don't do stack survey for cancelled lanes.
666 // 661 //
@@ -670,9 +665,7 @@ static int lane_error( lua_State* L)
670 } 665 }
671 666
672 STACK_GROW(L, 3); 667 STACK_GROW(L, 3);
673 EXTENDED_STACKTRACE_REGKEY.query_registry(L); // some_error basic|extended 668 bool const extended{ EXTENDED_STACKTRACE_REGKEY.readBoolValue(L) };
674 bool const extended{ lua_toboolean(L, -1) ? true : false};
675 lua_pop(L, 1); // some_error
676 STACK_CHECK(L, 1); 669 STACK_CHECK(L, 1);
677 670
678 // Place stack trace at 'registry[STACKTRACE_REGKEY]' for the 'lua_pcall()' 671 // Place stack trace at 'registry[STACKTRACE_REGKEY]' for the 'lua_pcall()'
@@ -685,7 +678,7 @@ static int lane_error( lua_State* L)
685 // 678 //
686 // table of { "sourcefile.lua:<line>", ... } 679 // table of { "sourcefile.lua:<line>", ... }
687 // 680 //
688 lua_newtable( L); // some_error {} 681 lua_newtable(L); // some_error {}
689 682
690 // Best to start from level 1, but in some cases it might be a C function 683 // Best to start from level 1, but in some cases it might be a C function
691 // and we don't get '.currentline' for that. It's okay - just keep level 684 // and we don't get '.currentline' for that. It's okay - just keep level
@@ -697,7 +690,7 @@ static int lane_error( lua_State* L)
697 lua_getinfo(L, extended ? "Sln" : "Sl", &ar); 690 lua_getinfo(L, extended ? "Sln" : "Sl", &ar);
698 if (extended) 691 if (extended)
699 { 692 {
700 lua_newtable( L); // some_error {} {} 693 lua_newtable(L); // some_error {} {}
701 694
702 lua_pushstring(L, ar.source); // some_error {} {} source 695 lua_pushstring(L, ar.source); // some_error {} {} source
703 lua_setfield(L, -2, "source"); // some_error {} {} 696 lua_setfield(L, -2, "source"); // some_error {} {}
@@ -726,7 +719,7 @@ static int lane_error( lua_State* L)
726 } 719 }
727 720
728 // store the stack trace table in the registry 721 // store the stack trace table in the registry
729 STACKTRACE_REGKEY.set_registry(L, [](lua_State* L) { lua_insert(L, -2); }); // some_error 722 STACKTRACE_REGKEY.setValue(L, [](lua_State* L) { lua_insert(L, -2); }); // some_error
730 723
731 STACK_CHECK(L, 1); 724 STACK_CHECK(L, 1);
732 return 1; // the untouched error value 725 return 1; // the untouched error value
@@ -748,7 +741,7 @@ static void push_stack_trace( lua_State* L, int rc_, int stk_base_)
748 // fetch the call stack table from the registry where the handler stored it 741 // fetch the call stack table from the registry where the handler stored it
749 STACK_GROW(L, 1); 742 STACK_GROW(L, 1);
750 // yields nil if no stack was generated (in case of cancellation for example) 743 // yields nil if no stack was generated (in case of cancellation for example)
751 STACKTRACE_REGKEY.query_registry(L); // err trace|nil 744 STACKTRACE_REGKEY.pushValue(L); // err trace|nil
752 STACK_CHECK(L, 1); 745 STACK_CHECK(L, 1);
753 746
754 // For cancellation the error message is CANCEL_ERROR, and a stack trace isn't placed 747 // For cancellation the error message is CANCEL_ERROR, and a stack trace isn't placed
@@ -780,7 +773,7 @@ LUAG_FUNC(set_debug_threadname)
780 lua_settop(L, 1); 773 lua_settop(L, 1);
781 STACK_CHECK_START_ABS(L, 1); 774 STACK_CHECK_START_ABS(L, 1);
782 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... 775 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global...
783 hidden_regkey.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); 776 hidden_regkey.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); });
784 STACK_CHECK(L, 1); 777 STACK_CHECK(L, 1);
785 lane->debug_name = lua_tostring(L, -1); 778 lane->debug_name = lua_tostring(L, -1);
786 // keep a direct pointer on the string 779 // keep a direct pointer on the string
@@ -1213,7 +1206,7 @@ LUAG_FUNC( lane_new)
1213 STACK_CHECK_RESET_REL(L, 0); 1206 STACK_CHECK_RESET_REL(L, 0);
1214 STACK_CHECK( L2, 1 + nargs); 1207 STACK_CHECK( L2, 1 + nargs);
1215 1208
1216 // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) 1209 // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread)
1217 // 1210 //
1218 // a Lane full userdata needs a single uservalue 1211 // a Lane full userdata needs a single uservalue
1219 Lane** const ud{ lua_newuserdatauv<Lane*>(L, 1) }; // func libs priority globals package required gc_cb lane 1212 Lane** const ud{ lua_newuserdatauv<Lane*>(L, 1) }; // func libs priority globals package required gc_cb lane
@@ -1257,15 +1250,15 @@ LUAG_FUNC( lane_new)
1257 // Store the gc_cb callback in the uservalue 1250 // Store the gc_cb callback in the uservalue
1258 if (gc_cb_idx > 0) 1251 if (gc_cb_idx > 0)
1259 { 1252 {
1260 GCCB_KEY.push(L); // func libs priority globals package required gc_cb lane uv k 1253 GCCB_KEY.pushKey(L); // func libs priority globals package required gc_cb lane uv k
1261 lua_pushvalue(L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb 1254 lua_pushvalue(L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb
1262 lua_rawset(L, -3); // func libs priority globals package required gc_cb lane uv 1255 lua_rawset(L, -3); // func libs priority globals package required gc_cb lane uv
1263 } 1256 }
1264 1257
1265 lua_setiuservalue(L, -2, 1); // func libs priority globals package required gc_cb lane 1258 lua_setiuservalue(L, -2, 1); // func libs priority globals package required gc_cb lane
1266 1259
1267 // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). 1260 // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive).
1268 CANCEL_TEST_KEY.set_registry(L2, [lane](lua_State* L) { lua_pushlightuserdata(L, lane); }); // func [... args ...] 1261 LANE_POINTER_REGKEY.setValue(L2, [lane](lua_State* L) { lua_pushlightuserdata(L, lane); }); // func [... args ...]
1269 1262
1270 STACK_CHECK(L, 1); 1263 STACK_CHECK(L, 1);
1271 STACK_CHECK( L2, 1 + nargs); 1264 STACK_CHECK( L2, 1 + nargs);
@@ -1298,7 +1291,7 @@ LUAG_FUNC(thread_gc)
1298 1291
1299 // if there a gc callback? 1292 // if there a gc callback?
1300 lua_getiuservalue(L, 1, 1); // ud uservalue 1293 lua_getiuservalue(L, 1, 1); // ud uservalue
1301 GCCB_KEY.push(L); // ud uservalue __gc 1294 GCCB_KEY.pushKey(L); // ud uservalue __gc
1302 lua_rawget(L, -2); // ud uservalue gc_cb|nil 1295 lua_rawget(L, -2); // ud uservalue gc_cb|nil
1303 if (!lua_isnil(L, -1)) 1296 if (!lua_isnil(L, -1))
1304 { 1297 {
@@ -1988,12 +1981,12 @@ LUAG_FUNC(configure)
1988 lua_pushinteger(L, THREAD_PRIO_MAX); // settings M THREAD_PRIO_MAX 1981 lua_pushinteger(L, THREAD_PRIO_MAX); // settings M THREAD_PRIO_MAX
1989 lua_setfield(L, -2, "max_prio"); // settings M 1982 lua_setfield(L, -2, "max_prio"); // settings M
1990 1983
1991 CANCEL_ERROR.push(L); // settings M CANCEL_ERROR 1984 CANCEL_ERROR.pushKey(L); // settings M CANCEL_ERROR
1992 lua_setfield(L, -2, "cancel_error"); // settings M 1985 lua_setfield(L, -2, "cancel_error"); // settings M
1993 1986
1994 STACK_CHECK(L, 2); // reference stack contains only the function argument 'settings' 1987 STACK_CHECK(L, 2); // reference stack contains only the function argument 'settings'
1995 // we'll need this every time we transfer some C function from/to this state 1988 // we'll need this every time we transfer some C function from/to this state
1996 LOOKUP_REGKEY.set_registry(L, [](lua_State* L) { lua_newtable(L); }); // settings M 1989 LOOKUP_REGKEY.setValue(L, [](lua_State* L) { lua_newtable(L); }); // settings M
1997 STACK_CHECK(L, 2); 1990 STACK_CHECK(L, 2);
1998 1991
1999 // register all native functions found in that module in the transferable functions database 1992 // register all native functions found in that module in the transferable functions database
@@ -2016,7 +2009,7 @@ LUAG_FUNC(configure)
2016 lua_pop(L, 1); // settings 2009 lua_pop(L, 1); // settings
2017 2010
2018 // set _R[CONFIG_REGKEY] = settings 2011 // set _R[CONFIG_REGKEY] = settings
2019 CONFIG_REGKEY.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); 2012 CONFIG_REGKEY.setValue(L, [](lua_State* L) { lua_pushvalue(L, -2); });
2020 STACK_CHECK(L, 1); 2013 STACK_CHECK(L, 1);
2021 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); 2014 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L));
2022 DEBUGSPEW_CODE(--U->debugspew_indent_depth); 2015 DEBUGSPEW_CODE(--U->debugspew_indent_depth);
@@ -2105,11 +2098,11 @@ LANES_API int luaopen_lanes_core( lua_State* L)
2105 2098
2106 // Create main module interface table 2099 // Create main module interface table
2107 // we only have 1 closure, which must be called to configure Lanes 2100 // we only have 1 closure, which must be called to configure Lanes
2108 lua_newtable( L); // M 2101 lua_newtable(L); // M
2109 lua_pushvalue(L, 1); // M "lanes.core" 2102 lua_pushvalue(L, 1); // M "lanes.core"
2110 lua_pushvalue(L, -2); // M "lanes.core" M 2103 lua_pushvalue(L, -2); // M "lanes.core" M
2111 lua_pushcclosure(L, LG_configure, 2); // M LG_configure() 2104 lua_pushcclosure(L, LG_configure, 2); // M LG_configure()
2112 CONFIG_REGKEY.query_registry(L); // M LG_configure() settings 2105 CONFIG_REGKEY.pushValue(L); // M LG_configure() settings
2113 if (!lua_isnil(L, -1)) // this is not the first require "lanes.core": call configure() immediately 2106 if (!lua_isnil(L, -1)) // this is not the first require "lanes.core": call configure() immediately
2114 { 2107 {
2115 lua_pushvalue(L, -1); // M LG_configure() settings settings 2108 lua_pushvalue(L, -1); // M LG_configure() settings settings