From b482ed9c30cddac31dcff2d19e517bf20af30d10 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 27 May 2024 14:47:56 +0200 Subject: More string_view --- Makefile | 4 ++++ src/compat.h | 10 ++++++++++ src/lanes.cpp | 2 +- src/linda.cpp | 12 ++++++------ src/state.cpp | 15 ++++++++------- src/state.h | 2 +- tests/nameof.lua | 28 ++++++++++++++++++++++++---- 7 files changed, 54 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 742e7a8..52f4976 100644 --- a/Makefile +++ b/Makefile @@ -90,6 +90,7 @@ test: $(MAKE) keeper $(MAKE) linda_perf $(MAKE) manual_register + $(MAKE) nameof $(MAKE) objects $(MAKE) package $(MAKE) pingpong @@ -161,6 +162,9 @@ linda_perf: tests/linda_perf.lua $(_TARGET_SO) manual_register: tests/manual_register.lua $(_TARGET_SO) $(_PREFIX) $(LUA) $< +nameof: tests/nameof.lua $(_TARGET_SO) + $(_PREFIX) $(LUA) $< + objects: tests/objects.lua $(_TARGET_SO) $(_PREFIX) $(LUA) $< 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_); return std::string_view{ _str, _len }; } +[[nodiscard]] inline std::string_view luaL_optstringview(lua_State* L_, int idx_, std::string_view const& default_) +{ + if (lua_isnoneornil(L_, idx_)) { + return default_; + } + size_t _len{ 0 }; + char const* _str{ luaL_optlstring(L_, idx_, default_.data(), &_len) }; + return std::string_view{ _str, _len }; +} + [[nodiscard]] inline std::string_view lua_pushstringview(lua_State* L_, std::string_view const& str_) { #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) Universe* const _U{ universe_get(L_) }; DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: setup" << std::endl); - char const* const _libs_str{ lua_tostring(L_, kLibsIdx) }; + std::optional _libs_str{ lua_isnil(L_, kLibsIdx) ? std::nullopt : std::make_optional(lua_tostringview(L_, kLibsIdx)) }; lua_State* const _L2{ luaG_newstate(_U, SourceState{ L_ }, _libs_str) }; // L_: [fixed] ... L2: STACK_CHECK_START_REL(_L2, 0); 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_) LUAG_FUNC(linda_cancel) { Linda* const _linda{ ToLinda(L_, 1) }; - char const* _who{ luaL_optstring(L_, 2, "both") }; - // make sure we got 3 arguments: the linda, a key and a limit + std::string_view const _who{ luaL_optstringview(L_, 2, "both") }; + // make sure we got 2 arguments: the linda and the cancellation mode luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); _linda->cancelRequest = CancelRequest::Soft; - if (strcmp(_who, "both") == 0) { // tell everyone writers to wake up + if (_who == "both") { // tell everyone writers to wake up _linda->writeHappened.notify_all(); _linda->readHappened.notify_all(); - } else if (strcmp(_who, "none") == 0) { // reset flag + } else if (_who == "none") { // reset flag _linda->cancelRequest = CancelRequest::None; - } else if (strcmp(_who, "read") == 0) { // tell blocked readers to wake up + } else if (_who == "read") { // tell blocked readers to wake up _linda->writeHappened.notify_all(); - } else if (strcmp(_who, "write") == 0) { // tell blocked writers to wake up + } else if (_who == "write") { // tell blocked writers to wake up _linda->readHappened.notify_all(); } else { 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 * *NOT* called for keeper states! * */ -lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) +lua_State* luaG_newstate(Universe* U_, SourceState from_, std::optional const& libs_) { DestState const _L{ create_state(U_, from_) }; @@ -336,7 +336,7 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) STACK_CHECK(_L, 0); // neither libs (not even 'base') nor special init func: we are done - if (libs_ == nullptr && U_->onStateCreateFunc == nullptr) { + if (!libs_.has_value() && U_->onStateCreateFunc == nullptr) { DEBUGSPEW_CODE(DebugSpew(U_) << "luaG_newstate(nullptr)" << std::endl); return _L; } @@ -351,15 +351,16 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) lua_gc(_L, LUA_GCSTOP, 0); // Anything causes 'base' and 'jit' to be taken in - if (libs_ != nullptr) { + std::string_view _libs{ libs_.value() }; + if (libs_.has_value()) { // special "*" case (mainly to help with LuaJIT compatibility) // as we are called from luaopen_lanes_core() already, and that would deadlock - if (libs_[0] == '*' && libs_[1] == 0) { + if (_libs == "*") { DEBUGSPEW_CODE(DebugSpew(U_) << "opening ALL standard libraries" << std::endl); luaL_openlibs(_L); // don't forget lanes.core for regular lane states open1lib(_L, kLanesCoreLibName); - libs_ = nullptr; // done with libs + _libs = ""; // done with libs } else { if constexpr (LUAJIT_FLAVOR() != 0) { // building against LuaJIT headers, always open jit DEBUGSPEW_CODE(DebugSpew(U_) << "opening 'jit' library" << std::endl); @@ -380,9 +381,9 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) STACK_CHECK(_L, 0); // scan all libraries, open them one by one - if (libs_) { + if (!_libs.empty()) { unsigned int _len{ 0 }; - for (char const* _p{ libs_ }; *_p; _p += _len) { + for (char const* _p{ _libs.data() }; *_p; _p += _len) { // skip delimiters ('.' can be part of name for "lanes.core") while (*_p && !isalnum(*_p) && *_p != '.') ++_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_); // ################################################################################################# [[nodiscard]] lua_State* create_state(Universe* U_, lua_State* from_); -[[nodiscard]] lua_State* luaG_newstate(Universe* U_, SourceState _from, char const* libs); +[[nodiscard]] lua_State* luaG_newstate(Universe* U_, SourceState from_, std::optional const& libs_); // ################################################################################################# 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 @@ -lanes = require "lanes".configure() +local lanes = require "lanes".configure() -print( lanes.nameof( {})) -print( lanes.nameof( string.sub)) -print( lanes.nameof( print)) +print("Name of table: ", lanes.nameof({})) +print("Name of string.sub: ", lanes.nameof(string.sub)) +print("Name of print: ", lanes.nameof(print)) + +-- a standalone function without any dependency +local body = function() + local n = 0 + for i = 1, 1e30 do + n = n + 1 + end +end + +-- start the lane without any library +local h = lanes.gen(nil, body)() +lanes.sleep(0.1) +print("Name of lane: ", lanes.nameof(h), "("..h.status..")") +assert(h.status == "running") +-- cancel the lane +h:cancel("line", 1) +lanes.sleep(0.1) +print("Name of lane: ", lanes.nameof(h), "("..h.status..")") +assert(h.status == "cancelled") +print "TEST OK" \ No newline at end of file -- cgit v1.2.3-55-g6feb