I couldn’t figure it out how to safely invoke lua callbacks from c++ thread.
Little info; I’m developing a NE for our multiplayer game using uWebSockets and msgpack(it may change).
Every socket connection has its own “thread” with lua callbacks like onConnect, onError, onMessage… I’m using two threats for now but it will be just one.
Everything works fine on desktop(mac) even when I hard on it. I believe it is because the processor speed.
But on ios(ipad 3 - ARMv7) I have bunch of “Assertion failed” crashes and I have no idea how to deal with them.
I couldn’t find any pattern of crashes. If I go slow on mobile everything works for a while(launch game->wait, open connection/threat->play-> wait, close connection->wait, <-loop). Also I’m having more crashes according the debug or release builds.
Assertion failed: (top + 2 == lua_gettop(L)), function lua_pushlistener
void lua_pushlistener(lua_State *L, struct lua_Listener &listener)
{
int top = lua_gettop(L);
// get the function callback from the registry and push it to the top of the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, listener.m_Callback);
// get self from registry and push it to the top of the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, listener.m_Self);
// push copy of self to top of the stack
lua_pushvalue(L, -1);
// set current script instance from top of the stack (and pop it)
dmScript::SetInstance(L);
assert(top + 2 == lua_gettop(L));
}
This is the method which I invoke callbacks on thread. event
is a struct
Assertion failed: (top == lua_gettop(L)), function handleEvents
void Connection::handleEvents(lua_Listener event)
{
if (event.m_Callback == LUA_NOREF)
{
return;
}
lua_State *L = event.m_L;
//Validate lua stack ??
DM_LUA_STACK_CHECK(L, 0);
int top = lua_gettop(L);
int ret;
//Invoke callback
lua_pushlistener(L, event);
if (Connection::protocolID == Protocols::JOIN_ROOM)
{
lua_pushinteger(L, Connection::protocolID); /* push 2st argument */
lua_pushstring(L, Connection::sessionid.c_str()); /* push 3nd argument */
lua_pushstring(L, Connection::roomname.c_str()); /* push 4nd argument */
ret = lua_pcall(L, 4, 0, 0);
}
else
{
ret = lua_pcall(L, 1, 0, 0);
}
if (ret != 0)
{
printf("Error while invoking process terminate callback: %s\n", lua_tostring(L, -1));
lua_pop(L, 1); // pop error message
}
assert(top == lua_gettop(L));
}
If I go hard on it and init the connection immediately on mobile when game launch I got other random crash (those script files are not related to me)
Each time, one of these:
Assertion failed: (top == lua_gettop(L)), function GetURL, file ../src/script.cpp, line 649.
Assertion failed: (n == lua_gettop(L)), function LuaPrint, file ../src/script.cpp, line 335.
Assertion failed: (top + 1 == lua_gettop(L)), function PushHash, file ../src/script_hash.cpp, line 191.
Assertion failed: (top + 1 == lua_gettop(L)), function PushHash, file ../src/script_hash.cpp, line 191.
Sorry for the long post.
I know it is not easy to solve this kind of problem by looking at a small part of it. But multiplayer server and client is the most important part of our game and I really want to continue with Defold.
Any suggestions are most welcome.