From e3bd98406260e33fb06bdd6c9e54284f0d88ce86 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Tue, 12 Sep 2017 22:01:29 -0400 Subject: [PATCH] cannot do automatic `lua_xmove` because of state differences --- docs/source/api/reference.rst | 2 +- docs/source/threading.rst | 2 -- single/sol/sol.hpp | 42 ++++++----------------------------- sol/reference.hpp | 36 ++++-------------------------- sol/thread.hpp | 2 +- tests/test_coroutines.cpp | 6 +++-- 6 files changed, 17 insertions(+), 73 deletions(-) diff --git a/docs/source/api/reference.rst b/docs/source/api/reference.rst index b4b2b1d0..415f4b68 100644 --- a/docs/source/api/reference.rst +++ b/docs/source/api/reference.rst @@ -35,7 +35,7 @@ members The first constructor creates a reference from the Lua stack at the specified index, saving it into the metatable registry. The second attemtps to register something that already exists in the registry. The third attempts to reference a pre-existing object and create a reference to it. These constructors are exposed on all types that derive from ``sol::reference``, meaning that you can grab tables, functions, and coroutines from the registry, stack, or from other objects easily. -Note that the last constructor, and the copy/move assignment operations, also have ``lua_xmove`` safety built into it. You can pin an object to a certain thread (or the main thread) by initializing it with ``sol::reference pinned(state, sol::lua_nil);``, or any ``sol::reference`` derived type. +Note that the last constructor have ``lua_xmove`` safety built into it. You can pin an object to a certain thread (or the main thread) by initializing it with ``sol::reference pinned(state, other_reference_object);``. This ensures that ``other_reference_object`` will exist in the state/thread of ``state``. This applies for any ``sol::reference`` derived type. .. code-block:: cpp :caption: function: push referred-to element from the stack diff --git a/docs/source/threading.rst b/docs/source/threading.rst index bba2f9e5..fc18ec32 100644 --- a/docs/source/threading.rst +++ b/docs/source/threading.rst @@ -18,8 +18,6 @@ working with multiple Lua threads You can mitigate some of the pressure of using coroutines and threading by using the ``lua_xmove`` constructors that sol implements. Simply keep a reference to your ``sol::state_view`` or ``sol::state`` or the target ``lua_State*`` pointer, and pass it into the constructor along with the object you want to copy. -Note that copy and move assignment operators -- when you create a :doc:`sol::reference`-derived type like ``sol::table`` or ``sol::function`` -- also have the ``lua_xmove`` functionality built in: just make sure to initialize your types with ``sol::function f(target_state, sol::lua_nil_t);`` to lock that type onto that thread when using a copy assignment or move assignment operator. Below is an example of using the pinning thread: - .. code-block:: cpp :caption: transfer from state function :name: state-transfer diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index f81a2f4c..ae75b59e 100644 --- a/single/sol/sol.hpp +++ b/single/sol/sol.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2017-09-12 23:51:14.830850 UTC -// This header was generated with sol v2.18.2 (revision e201f85) +// Generated 2017-09-13 01:59:58.724391 UTC +// This header was generated with sol v2.18.2 (revision 0325e27) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -5809,25 +5809,9 @@ namespace sol { if (valid()) { deref(); } - if (lua_state() != o.lua_state() && lua_state() != nullptr) { - // different state (different threads???) - if (o.lua_state() != nullptr) { - // both are valid but different? - o.push(lua_state()); - ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); - return *this; - } - else { - luastate = o.luastate; - ref = o.ref; - } - } - else { - // same state, or this state is nullptr - luastate = o.luastate; - ref = o.ref; - } - + luastate = o.luastate; + ref = o.ref; + o.luastate = nullptr; o.ref = LUA_NOREF; @@ -5838,19 +5822,7 @@ namespace sol { if (valid()) { deref(); } - if (lua_state() != o.lua_state() && lua_state() != nullptr) { - // different state (different threads???) - if (o.lua_state() != nullptr) { - // both are valid but different? - o.push(lua_state()); - ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); - } - else { - luastate = o.luastate; - ref = o.ref; - } - return *this; - } + luastate = o.luastate; ref = o.copy(); return *this; @@ -18066,7 +18038,7 @@ namespace sol { optional get(lua_State* L, int index, Handler&& handler, record& tracking) { lua_thread_state lts{ lua_tothread(L, index) }; if (lts.L == nullptr) { - handler(L, index, type::thread, type_of(L, index), "value does is not a valid thread type"); + handler(L, index, type::thread, type_of(L, index), "value is not a valid thread type"); return nullopt; } tracking.use(1); diff --git a/sol/reference.hpp b/sol/reference.hpp index ec89e910..b005a0cb 100644 --- a/sol/reference.hpp +++ b/sol/reference.hpp @@ -199,25 +199,9 @@ namespace sol { if (valid()) { deref(); } - if (lua_state() != o.lua_state() && lua_state() != nullptr) { - // different state (different threads???) - if (o.lua_state() != nullptr) { - // both are valid but different? - o.push(lua_state()); - ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); - return *this; - } - else { - luastate = o.luastate; - ref = o.ref; - } - } - else { - // same state, or this state is nullptr - luastate = o.luastate; - ref = o.ref; - } - + luastate = o.luastate; + ref = o.ref; + o.luastate = nullptr; o.ref = LUA_NOREF; @@ -228,19 +212,7 @@ namespace sol { if (valid()) { deref(); } - if (lua_state() != o.lua_state() && lua_state() != nullptr) { - // different state (different threads???) - if (o.lua_state() != nullptr) { - // both are valid but different? - o.push(lua_state()); - ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); - } - else { - luastate = o.luastate; - ref = o.ref; - } - return *this; - } + luastate = o.luastate; ref = o.copy(); return *this; diff --git a/sol/thread.hpp b/sol/thread.hpp index c23b0896..2cfc9c7f 100644 --- a/sol/thread.hpp +++ b/sol/thread.hpp @@ -60,7 +60,7 @@ namespace sol { optional get(lua_State* L, int index, Handler&& handler, record& tracking) { lua_thread_state lts{ lua_tothread(L, index) }; if (lts.L == nullptr) { - handler(L, index, type::thread, type_of(L, index), "value does is not a valid thread type"); + handler(L, index, type::thread, type_of(L, index), "value is not a valid thread type"); return nullopt; } tracking.use(1); diff --git a/tests/test_coroutines.cpp b/tests/test_coroutines.cpp index 57fa0693..117ce99e 100644 --- a/tests/test_coroutines.cpp +++ b/tests/test_coroutines.cpp @@ -149,11 +149,13 @@ co = nil } void store(sol::table ref) { - obj = std::move(ref); + // must be explicit + obj = sol::reference(obj.lua_state(), ref); } void copy_store(sol::table ref) { - obj = ref; + // must be explicit + obj = sol::reference(obj.lua_state(), ref); } sol::reference get() {