cannot do automatic lua_xmove because of state differences

This commit is contained in:
ThePhD 2017-09-12 22:01:29 -04:00
parent 0325e27454
commit e3bd984062
6 changed files with 17 additions and 73 deletions

View File

@ -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

View File

@ -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<api/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

View File

@ -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<lua_thread_state> 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);

View File

@ -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;

View File

@ -60,7 +60,7 @@ namespace sol {
optional<lua_thread_state> 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);

View File

@ -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() {