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?
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.
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.
Related
In vxWorks 6.9 you can create timers, which are really just wrappers for a watchdog. You supply these guys a function pointer, a delay, and up to one parameter, and after the delay the function is called with the parameter. However, it is called in the interrupt context. This (for some reason) means you cannot call any "blocking" functions or the system literally crashes. You cannot call printf and you cannot call upon an object's public function, ie you cannot do this:
void Foo::WdCallback(Foo *foo){
foo->DoThing();
}
wdStart(wd, 16, (FUNCPTR)Foo::WdCallback, (_Vx_usr_arg_t)my_foo_ptr);
as it will also crash for reasons I don't understand.
What other way can we create a timer/timeout in vxWorks so that we can actually do something useful with the callback? One method I have seen is using a message queue - the watchdog function will call upon a message queue send function. However this means that a task must be created to dequeue that message queue somewhere else. I've also read that the watchdog callback could give a semaphore allowing a task to continue, but that means we have to create a task for every single timer-based function we want..
It looks like no matter what road we take with watchdogs, or timers, in vxWorks, we have to create an entire task just to be able to handle the watchdog callback due to the interupt context. There has to be a less ridiculous way to do this. Is there a purely C++ way to write a timer? Or a simpler vxWorks implementation?
C++ shall not be used for function being executed in an interrupt context. The watchdog here is executed in the context of the system tick interrupt.
If you want to keep C++ code, make sure that no new/delete operation will be performed and you would need to compile the code with addition flags (this should be documented in the VxWorks Programmer's Guide at the C++ section => -fno-rtti -fno-exceptions).
Is there a way to know which thread (coroutine) executing a Lua script is at the origin of a lua_pushcclosure call?
In order to manage some stuff relative to lua threads (delayed pause/resume, or private thread variables) I need to identify the thread involved in the callback. I know I can get the thread index when creating it by using lua_gettop, but I can't find a way to use it so it helps identifying the thread when a lua_pushcclosure call is issued from a Lua script.
My current system permits nested script calls, so a script can execute other scripts (each nested script call create a new thread with the same lua_state. Thus the lua_state used to get multiple thread entries in the stack.)
I'm using Lua 5.2
If you're in a C function that has been called from Lua, and you want to know what thread you're in... just call lua_pushthread(L).
I am trying to implement an audio module for nodejs which involves a neural network.
This neural network has 2 types of nodes
Pure C++
C++ based on JAVASCRIPT ( which involves calling a javascript
function )
As far as i know its not possible to call any function which involves v8 from a different thread. And if i return to the main thread i will lose my traverse in the neural network.
How to implement a call to a function in the main thread from a different thread?
I figured it out with the help of
#indutny in the #libuv channel.
What I do now is dispatch the call to main thread via
uv_async_send
function defined in libuv.h, since the function is non-blocking. I also use a semaphore to wait till the execution of the javascript function is complete in order to avoid the corrupted parse.
I'm working with in LUA's thread and I'm using lua_newthread for this in my code must perform the same function n times.
To work with the competition's thread instantiate some threads in C + + and for each thread assigns a lua_state this lua_state = lua_newthread.
This thread's are destroyed only at the end of the application, so I'm always reuse the attribute lua_state these thread's. My question is this,
after some run time, a crash happens in the application, this can be caused by the garbage collector?
In my last application I used the command lua_gc (thread, LUA_GCSTOP, 0), and yet the error persisted.
Another strategy I tried was the end of each run of lua_resume, I added the command lua_settop (thread, 0), so that the battery was drained and
did not consume any memory space.
Please help me, what can happen?
Lua threads are not like CPU-threads. Lua is not thread-safe; you cannot execute Lua code in parallel across actual threads. Lua allows for cooperative multitasking, but not real CPU-threads.
You can call into different actual lua_State objects from different CPU-threads, but only if they are truly separate. If you created a Lua thread from a root lua_State, then you cannot call Lua code on that Lua thread while also calling Lua code on the root lua_State. If two Lua threads share the same parent lua_State, you cannot be executing Lua code on both of these Lua threads at the same time.
So you need to restructure what you're doing. Instead of using a thread, use lua_newstate to create one Lua state for each CPU thread. Each lua_State will be completely independent of the rest.
What's the cheapest way for a JavaScript like setTimeout-function in C++?
I would need this:
5000 miliseconds from now, start function xy (no parameters, no return value).
The reason for this is I need to initialize COM for text to speech, but when I do it on dll attach, it crashes.
It works fine however if I do not call CoInitialize from dllmain.
I just need to call CoInitialize and CoCreateInstance, and then use the instance in other functions. I can catch the uninitialized instance by checking for NULL, but I need to initialize COM - without crashing.
Calling CoInitialize() from DllMain() is a bad thing to do; there are LOTS of restrictions on what you can do from DllMain(); see here: http://blogs.msdn.com/larryosterman/archive/2004/04/23/118979.aspx
Even if it DID work reliably then initialising COM from within DllMain() isn't an especially nice thing to do as COM is initialised per thread and you don't know what the application itself wants to do with regards to COM apartments for the thread that you want to initialise COM for... This means that you might initialise COM in one way and then the application might need to initialise it in another way and might fail because of what your DLL had done...
You COULD spin up a thread in DllMain() as long as you are careful (see here http://blogs.msdn.com/oldnewthing/archive/2007/09/04/4731478.aspx) and then initialise COM on that thread and do all your COM related work on that thread. You would need to marshal whatever data you need to use COM with from whatever thread you're called on to your own COM thread and make the COM call from there...
And then there's the question of whether the instance of the COM object that you create (could you reliably do what you want to do) would be usable from the thread that was calling into your DLL to make the call... You do understand how you'd have to marshal the interface pointer if required, etc?
Alternatively you should expose YOUR functionality via COM and then have the application load your DLL as a COM DLL and everything will work just fine. You can specify the apartment type that you need and the app is responsible for setting things up for you correctly.
So, in summary, you don't need the answer to your question.
When it is OK to stop the execution for 5 seconds entirely, you can use the Winapi Sleep function. Beware that the documentation of Sleep minds some possible problems with CoInitialize and Messages.