Reputation: 1
I'm pulling my hairs out (that I don't have) on a big problem, but probably simple one.
I'm developing a Server application in QT. This server will accept TCP connections and dialog with specific and proprietary Ethernet products.
Each time a product is called on this server, a new thread is created with this new TCP connection and a dialog begins with some "common" requests.
At a certain step of this dialog, the thread needs to run a Lua script to continue the process: not with a common procedure - but a specific one for each product.
This is my problem:
When I run the Lua script, I need to use methods of the Thread class (the current thread). Due to the Extern "C" declaration of C fonctions that can be used in Lua scripts I can't call the methods of my current thread, because I don't see how to program (or the principle behind) the structure of this exchange: - the thread have N methods to send data on IP depending of the protocol (we will call this methods mythread::CClass_fn_X()) - the registered function C for Lua will be call LUA_FN_X(). This is just a gateway to call CClass_fn_X() with computed parameters from Lua)
if in LUA_FN_X() I want to do a "this->CClass_fn_X()", I can't because C LUA function have no reference to "this" of the thread.
I've tried various things the past few days and I can't find a good solution (or simply any solution) for my problem.
Please help me, I'm not requiring code, but just the principle to do that.
Also, is the Lua interpreter thread safe? Can I run separately Lua scripts in different threads?
Upvotes: 0
Views: 750
Reputation: 29483
There are several ways to do this. If you only have one non-main thread that can call your Lua script, then your script just needs to know the thread object it belongs to and provide that as parameter when it calls into the C++. There are many strategies that can work there, but one is that you create a global variable that is a light userdata for your thread (basically a pointer or handle that is sufficient to identify thread). Then when you call your script, the script calls your C function with that light userdata: your C function must assume the userdata received is actually the pointer or handle or integer (whatever your strategy) for thread so then it can find the right Thread instance and call the appropriate method. For example, the C++ side:
// tell Lua which thread:
lua_pushlightuserdata(L, threadHandle); // threadHandle uniquely identifies thread
lua_setglobal(L, "scriptThread");
// call script:
// assumes you loaded script before and saved the compiled chunk
// as global variable "script" (other SO question shows how to do it)
lua_getglobal(L, "script");
lua_pcall(L, 0, 0, 0);
and the Lua script:
-- call C++ func:
LUA_FN_X(scriptThread);
and the C/C++ wrapper function that you registered in Lua state as LUA_FN_X:
void cwrapper(lua_State* L)
{
Thread* thread = (Thread*)lua_touserdata(L, -1);
thread->CClass_fn_X();
}
The Lua can't do much with a light userdata except pass it back to C++. If you want to query various thread methods, and there you have several thread instances that can call the Lua script, it might be worthwhile using a full userdata.
Upvotes: 0
Reputation: 72312
To answer your last question, Lua is not OS-thread safe if you use the same Lua state in different OS threads, but you can safely run different Lua states in different OS threads.
Do not confuse OS threads with Lua threads, which are coroutines and run in the same state.
Upvotes: 3