diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | src/compat.h | 10 | ||||
| -rw-r--r-- | src/lanes.cpp | 2 | ||||
| -rw-r--r-- | src/linda.cpp | 12 | ||||
| -rw-r--r-- | src/state.cpp | 15 | ||||
| -rw-r--r-- | src/state.h | 2 | ||||
| -rw-r--r-- | tests/nameof.lua | 28 |
7 files changed, 54 insertions, 19 deletions
| @@ -90,6 +90,7 @@ test: | |||
| 90 | $(MAKE) keeper | 90 | $(MAKE) keeper |
| 91 | $(MAKE) linda_perf | 91 | $(MAKE) linda_perf |
| 92 | $(MAKE) manual_register | 92 | $(MAKE) manual_register |
| 93 | $(MAKE) nameof | ||
| 93 | $(MAKE) objects | 94 | $(MAKE) objects |
| 94 | $(MAKE) package | 95 | $(MAKE) package |
| 95 | $(MAKE) pingpong | 96 | $(MAKE) pingpong |
| @@ -161,6 +162,9 @@ linda_perf: tests/linda_perf.lua $(_TARGET_SO) | |||
| 161 | manual_register: tests/manual_register.lua $(_TARGET_SO) | 162 | manual_register: tests/manual_register.lua $(_TARGET_SO) |
| 162 | $(_PREFIX) $(LUA) $< | 163 | $(_PREFIX) $(LUA) $< |
| 163 | 164 | ||
| 165 | nameof: tests/nameof.lua $(_TARGET_SO) | ||
| 166 | $(_PREFIX) $(LUA) $< | ||
| 167 | |||
| 164 | objects: tests/objects.lua $(_TARGET_SO) | 168 | objects: tests/objects.lua $(_TARGET_SO) |
| 165 | $(_PREFIX) $(LUA) $< | 169 | $(_PREFIX) $(LUA) $< |
| 166 | 170 | ||
diff --git a/src/compat.h b/src/compat.h index 139e606..b971a76 100644 --- a/src/compat.h +++ b/src/compat.h | |||
| @@ -264,6 +264,16 @@ LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); | |||
| 264 | return std::string_view{ _str, _len }; | 264 | return std::string_view{ _str, _len }; |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | [[nodiscard]] inline std::string_view luaL_optstringview(lua_State* L_, int idx_, std::string_view const& default_) | ||
| 268 | { | ||
| 269 | if (lua_isnoneornil(L_, idx_)) { | ||
| 270 | return default_; | ||
| 271 | } | ||
| 272 | size_t _len{ 0 }; | ||
| 273 | char const* _str{ luaL_optlstring(L_, idx_, default_.data(), &_len) }; | ||
| 274 | return std::string_view{ _str, _len }; | ||
| 275 | } | ||
| 276 | |||
| 267 | [[nodiscard]] inline std::string_view lua_pushstringview(lua_State* L_, std::string_view const& str_) | 277 | [[nodiscard]] inline std::string_view lua_pushstringview(lua_State* L_, std::string_view const& str_) |
| 268 | { | 278 | { |
| 269 | #if LUA_VERSION_NUM == 501 | 279 | #if LUA_VERSION_NUM == 501 |
diff --git a/src/lanes.cpp b/src/lanes.cpp index 6eec8c4..0369171 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
| @@ -238,7 +238,7 @@ LUAG_FUNC(lane_new) | |||
| 238 | Universe* const _U{ universe_get(L_) }; | 238 | Universe* const _U{ universe_get(L_) }; |
| 239 | DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: setup" << std::endl); | 239 | DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: setup" << std::endl); |
| 240 | 240 | ||
| 241 | char const* const _libs_str{ lua_tostring(L_, kLibsIdx) }; | 241 | std::optional<std::string_view> _libs_str{ lua_isnil(L_, kLibsIdx) ? std::nullopt : std::make_optional(lua_tostringview(L_, kLibsIdx)) }; |
| 242 | lua_State* const _L2{ luaG_newstate(_U, SourceState{ L_ }, _libs_str) }; // L_: [fixed] ... L2: | 242 | lua_State* const _L2{ luaG_newstate(_U, SourceState{ L_ }, _libs_str) }; // L_: [fixed] ... L2: |
| 243 | STACK_CHECK_START_REL(_L2, 0); | 243 | STACK_CHECK_START_REL(_L2, 0); |
| 244 | 244 | ||
diff --git a/src/linda.cpp b/src/linda.cpp index 87aa8fa..dafac56 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
| @@ -226,19 +226,19 @@ void Linda::setName(std::string_view const& name_) | |||
| 226 | LUAG_FUNC(linda_cancel) | 226 | LUAG_FUNC(linda_cancel) |
| 227 | { | 227 | { |
| 228 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 228 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 229 | char const* _who{ luaL_optstring(L_, 2, "both") }; | 229 | std::string_view const _who{ luaL_optstringview(L_, 2, "both") }; |
| 230 | // make sure we got 3 arguments: the linda, a key and a limit | 230 | // make sure we got 2 arguments: the linda and the cancellation mode |
| 231 | luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); | 231 | luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); |
| 232 | 232 | ||
| 233 | _linda->cancelRequest = CancelRequest::Soft; | 233 | _linda->cancelRequest = CancelRequest::Soft; |
| 234 | if (strcmp(_who, "both") == 0) { // tell everyone writers to wake up | 234 | if (_who == "both") { // tell everyone writers to wake up |
| 235 | _linda->writeHappened.notify_all(); | 235 | _linda->writeHappened.notify_all(); |
| 236 | _linda->readHappened.notify_all(); | 236 | _linda->readHappened.notify_all(); |
| 237 | } else if (strcmp(_who, "none") == 0) { // reset flag | 237 | } else if (_who == "none") { // reset flag |
| 238 | _linda->cancelRequest = CancelRequest::None; | 238 | _linda->cancelRequest = CancelRequest::None; |
| 239 | } else if (strcmp(_who, "read") == 0) { // tell blocked readers to wake up | 239 | } else if (_who == "read") { // tell blocked readers to wake up |
| 240 | _linda->writeHappened.notify_all(); | 240 | _linda->writeHappened.notify_all(); |
| 241 | } else if (strcmp(_who, "write") == 0) { // tell blocked writers to wake up | 241 | } else if (_who == "write") { // tell blocked writers to wake up |
| 242 | _linda->readHappened.notify_all(); | 242 | _linda->readHappened.notify_all(); |
| 243 | } else { | 243 | } else { |
| 244 | raise_luaL_error(L_, "unknown wake hint '%s'", _who); | 244 | raise_luaL_error(L_, "unknown wake hint '%s'", _who); |
diff --git a/src/state.cpp b/src/state.cpp index ebe4097..5a1d2fb 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
| @@ -319,7 +319,7 @@ void CallOnStateCreate(Universe* U_, lua_State* L_, lua_State* from_, LookupMode | |||
| 319 | * *NOT* called for keeper states! | 319 | * *NOT* called for keeper states! |
| 320 | * | 320 | * |
| 321 | */ | 321 | */ |
| 322 | lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | 322 | lua_State* luaG_newstate(Universe* U_, SourceState from_, std::optional<std::string_view> const& libs_) |
| 323 | { | 323 | { |
| 324 | DestState const _L{ create_state(U_, from_) }; | 324 | DestState const _L{ create_state(U_, from_) }; |
| 325 | 325 | ||
| @@ -336,7 +336,7 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | |||
| 336 | STACK_CHECK(_L, 0); | 336 | STACK_CHECK(_L, 0); |
| 337 | 337 | ||
| 338 | // neither libs (not even 'base') nor special init func: we are done | 338 | // neither libs (not even 'base') nor special init func: we are done |
| 339 | if (libs_ == nullptr && U_->onStateCreateFunc == nullptr) { | 339 | if (!libs_.has_value() && U_->onStateCreateFunc == nullptr) { |
| 340 | DEBUGSPEW_CODE(DebugSpew(U_) << "luaG_newstate(nullptr)" << std::endl); | 340 | DEBUGSPEW_CODE(DebugSpew(U_) << "luaG_newstate(nullptr)" << std::endl); |
| 341 | return _L; | 341 | return _L; |
| 342 | } | 342 | } |
| @@ -351,15 +351,16 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | |||
| 351 | lua_gc(_L, LUA_GCSTOP, 0); | 351 | lua_gc(_L, LUA_GCSTOP, 0); |
| 352 | 352 | ||
| 353 | // Anything causes 'base' and 'jit' to be taken in | 353 | // Anything causes 'base' and 'jit' to be taken in |
| 354 | if (libs_ != nullptr) { | 354 | std::string_view _libs{ libs_.value() }; |
| 355 | if (libs_.has_value()) { | ||
| 355 | // special "*" case (mainly to help with LuaJIT compatibility) | 356 | // special "*" case (mainly to help with LuaJIT compatibility) |
| 356 | // as we are called from luaopen_lanes_core() already, and that would deadlock | 357 | // as we are called from luaopen_lanes_core() already, and that would deadlock |
| 357 | if (libs_[0] == '*' && libs_[1] == 0) { | 358 | if (_libs == "*") { |
| 358 | DEBUGSPEW_CODE(DebugSpew(U_) << "opening ALL standard libraries" << std::endl); | 359 | DEBUGSPEW_CODE(DebugSpew(U_) << "opening ALL standard libraries" << std::endl); |
| 359 | luaL_openlibs(_L); | 360 | luaL_openlibs(_L); |
| 360 | // don't forget lanes.core for regular lane states | 361 | // don't forget lanes.core for regular lane states |
| 361 | open1lib(_L, kLanesCoreLibName); | 362 | open1lib(_L, kLanesCoreLibName); |
| 362 | libs_ = nullptr; // done with libs | 363 | _libs = ""; // done with libs |
| 363 | } else { | 364 | } else { |
| 364 | if constexpr (LUAJIT_FLAVOR() != 0) { // building against LuaJIT headers, always open jit | 365 | if constexpr (LUAJIT_FLAVOR() != 0) { // building against LuaJIT headers, always open jit |
| 365 | DEBUGSPEW_CODE(DebugSpew(U_) << "opening 'jit' library" << std::endl); | 366 | DEBUGSPEW_CODE(DebugSpew(U_) << "opening 'jit' library" << std::endl); |
| @@ -380,9 +381,9 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | |||
| 380 | STACK_CHECK(_L, 0); | 381 | STACK_CHECK(_L, 0); |
| 381 | 382 | ||
| 382 | // scan all libraries, open them one by one | 383 | // scan all libraries, open them one by one |
| 383 | if (libs_) { | 384 | if (!_libs.empty()) { |
| 384 | unsigned int _len{ 0 }; | 385 | unsigned int _len{ 0 }; |
| 385 | for (char const* _p{ libs_ }; *_p; _p += _len) { | 386 | for (char const* _p{ _libs.data() }; *_p; _p += _len) { |
| 386 | // skip delimiters ('.' can be part of name for "lanes.core") | 387 | // skip delimiters ('.' can be part of name for "lanes.core") |
| 387 | while (*_p && !isalnum(*_p) && *_p != '.') | 388 | while (*_p && !isalnum(*_p) && *_p != '.') |
| 388 | ++_p; | 389 | ++_p; |
diff --git a/src/state.h b/src/state.h index 5334c90..a97fdab 100644 --- a/src/state.h +++ b/src/state.h | |||
| @@ -12,7 +12,7 @@ void serialize_require(lua_State* L_); | |||
| 12 | // ################################################################################################# | 12 | // ################################################################################################# |
| 13 | 13 | ||
| 14 | [[nodiscard]] lua_State* create_state(Universe* U_, lua_State* from_); | 14 | [[nodiscard]] lua_State* create_state(Universe* U_, lua_State* from_); |
| 15 | [[nodiscard]] lua_State* luaG_newstate(Universe* U_, SourceState _from, char const* libs); | 15 | [[nodiscard]] lua_State* luaG_newstate(Universe* U_, SourceState from_, std::optional<std::string_view> const& libs_); |
| 16 | 16 | ||
| 17 | // ################################################################################################# | 17 | // ################################################################################################# |
| 18 | 18 | ||
diff --git a/tests/nameof.lua b/tests/nameof.lua index 221c893..79d5760 100644 --- a/tests/nameof.lua +++ b/tests/nameof.lua | |||
| @@ -1,5 +1,25 @@ | |||
| 1 | lanes = require "lanes".configure() | 1 | local lanes = require "lanes".configure() |
| 2 | 2 | ||
| 3 | print( lanes.nameof( {})) | 3 | print("Name of table: ", lanes.nameof({})) |
| 4 | print( lanes.nameof( string.sub)) | 4 | print("Name of string.sub: ", lanes.nameof(string.sub)) |
| 5 | print( lanes.nameof( print)) | 5 | print("Name of print: ", lanes.nameof(print)) |
| 6 | |||
| 7 | -- a standalone function without any dependency | ||
| 8 | local body = function() | ||
| 9 | local n = 0 | ||
| 10 | for i = 1, 1e30 do | ||
| 11 | n = n + 1 | ||
| 12 | end | ||
| 13 | end | ||
| 14 | |||
| 15 | -- start the lane without any library | ||
| 16 | local h = lanes.gen(nil, body)() | ||
| 17 | lanes.sleep(0.1) | ||
| 18 | print("Name of lane: ", lanes.nameof(h), "("..h.status..")") | ||
| 19 | assert(h.status == "running") | ||
| 20 | -- cancel the lane | ||
| 21 | h:cancel("line", 1) | ||
| 22 | lanes.sleep(0.1) | ||
| 23 | print("Name of lane: ", lanes.nameof(h), "("..h.status..")") | ||
| 24 | assert(h.status == "cancelled") | ||
| 25 | print "TEST OK" \ No newline at end of file | ||
