C++ Multithreading Run function on main thread - multithreading

I have a thread with a TCP Socket that connects to a server and waits for data in a while loop, so the thread never ends. When the socket receives data, it is parsed, and based on the opcode of the packet, should call x function. Whats the fastest/best way to go about that?
I read around that doing some kind of task/message queue system is a way of doing it, but not sure if there is any better options.
Should mention that I can not use boost:
Edit: Sorry, half asleep haha.
Here is the loop from thread x:
while (Running)
{
if (client.IsConnected())
{
Recieve();
}
FPlatformProcess::Sleep(0.01);
}
In the Receive function, it parses the data, and based on the packet opcode, I need to be able to call a function on the main thread (the GUI thread), because a lot of the packets are to spawn GUI objects, and I can't create GUI objects from any other thread than the main one.
So basically: I have a main thread, that spawns a new thread that enters a loop, listens for data, and I need to be able to call a function from the 2nd thread that runs on the main thread.

Related

Transmit Strings to Main thread from Background thread

I need to transmit Strings to Main thread (there is GUI) to add them to javafx' TextFlow.
In the background thread's run(), reader waits strings from JSch channel. On new stings it must transmit them to main thread. So main thread can't wait data from background thread (as it is GUI thread), and background thread must send some event with new Strings.
Another trouble, that in application can be, for example, 4 background threads, that reads some data from JSch channel and send it to one window to show.
To transmit data to the GUI thread,use Platfotm.runLater() method
Platform.runLater(() -> {
/*send your data from here*/
});
Platform.runLater makes you modify the GUI thread from other threads, It has a swing equivalent of SwingUtilities.invokeLater

Post event to nginx event loop from another thread

I have 3rd party library, which is nonblocking and has its own event loop, it accepts pointer of callback function and executes it in same thread. What I want is to post event from this thread to nginx main thread, something like ngx_add_timer but without time option, to safely add event to nginx main event loop.
So very late to the party here, but I found this thread in my research and wanted to post the solution I came up with
Nginx has a mechanism to post from a worker thread - one that is perhaps running another event loop - to the main thread of the nginx worker process. That is 'ngx_post_event' which lets you post an event handler which will be invoked at some point in the future by the main thread.
You have to choose an event queue to post it on, but whatever you're doing, the answer is certainly &ngx_posted_events.
Here we come to the problem (and a solution): if you do this, your event handler will not get invoked in a timely manner because the main nginx worker process thread is waiting on i/o. It won't even deign to look at the posted events queue until it has some 'real' work to do from i/o.
The solution that's working for me currently (and bear in mind this is only on Linux), is to send the main thread a signal which will wake it up from its epoll_wait reverie so it can get to work on the pipeline coming from the other thread.
So here's what worked:
First grab the id of the worker process main thread and hold it in some process-global state:
// In you 'c' source:
static pthread_t nginx_thread;
// In some code that runs once at nginx startup (in my case the module's preconfiguration step)
nginx_thread = pthread_self();
Now when to post your callback you use the ngx_post_event call I mentioned earlier, then send a SIGIO signal to the main thread to wake up the epoll_wait operation
// Post the event and wake up the Nginx epoll event loop
ngx_post_event( event_ptr, &ngx_posted_events );
pthread_kill( nginx_thread, SIGIO );
The SIGIO event is handled in the main Nginx signal handler - and is ignored (well that's what the log says), but crucially, causes the posted events to be processed immediately.
That's it - and it seems to be working so far... please do point out anything stupid I've done.
To complete the story, you'll need the following #includes:
#include <pthread.h>
#include <signal.h>

Qt blocking threads and cross-thread communication

I want to ask a question about Application architecture1. There will be the main GUI thread for providing user interaction2. A Receive thread based on UDP socket that will receive UDP packets as they arrive (want this to be blocking.3. Another thread for sending event based as well as periodic UDP packets.How do I implement this architecture in Qt, basically i have following questions:1. For the Receive Thread, how do I make it blocking ?I know about readyRead() signal, and I can connect it to some slot that will process the datagram, but how do i loop this so that this thread does this forever. 2. In send Thread I can generate a signal form the GUI thread which will be received by the Sending Thread and a slot here will write some data on the socket, but again how will this thread survive when it has nothing to send, I mean loop, poll over something what ?
Use event loops in the secondary threads.
QThread::exec() starts the thread's event loop which will run until QThread::quit() is called. That should solve your "how to wait until something happens" problem. The default implementation of QThread::run() just calls exec(), so I'd go with that. You could set everything up in your main() method, e.g. for the sender thread:
//Create UI
MainWindow mainWindow;
mainWindow.show();
//set up sender thread and the `QObject` doing the actual work (Sender)
QThread senderThread;
Sender sender; //the object doing the actual sending
sender.moveToThread(&sender); //move sender to its thread
senderThread.start(); //starts the thread which will then enter the event loop
//connect UI to sender thread
QObject::connect(&mainWindow, SIGNAL(sendMessage(QString)), &sender, SLOT(sendMessage(QString)), Qt::QueuedConnection);
...
const int ret = app.exec(); // enter main event loop
`senderThread.quit();` //tell sender thread to quit its event loop
`senderThread.wait();` //wait until senderThread is done
`return ret;` // leave main
Sender would just be a QObject with a sendMessage() slot doing the sending, a QTimer plus another slot for the periodic UDP packages, etc.

Inject a thread with LD_PRELOAD and thread-safety

I'm working on a project to inject a shared library in a program with LD_PRELOAD.
My injected library creates a new thread when it is injected into the program. All logic happens in this thread (like analyzing network traffic and so on).
First you need to know this about the program that is being preloaded. It is a client application that encrypts every packet, written to a static buffer, that it sends to the server. I found the function that encrypts and sends the packets in the client and I was able to detour it. So now I can just modify the static buffer and let the 'send' function encrypt the buffer and send the buffer to the server.
But now I have a problem: what if I change contents of the static buffer in my library's thread (so that I can send a fake packet) and at the same time the program's thread changes the static buffer too? That would cause a crash.
I need some kind of synchronization.
So I've been thinking of some solutions:
Find every function in the program that changes the buffer, detour them and add a mutex to that call or something like that. Would take like ages though...
Find a way to execute my piece of code, that changes the buffer, in one block. So my piece of code actually gets executed at once, without POSIX threads switching to other threads. Is this even possible?
Make my application synchronous and cry.
Can anyone come up with a better solution? Or do you know how to make solution 2 possible?
Thanks in advance,
Gillis
If you detoured the 'send' function and you have the code of your 'detoured send' in your preloaded library it means that when the main thread calls 'send', your 'detoured send' code will be executed in the main thread's context, your thread is doing nothing at that moment. If you have more than one 'main thread' that could potentially call 'send', then you need synchronization in your 'detoured send'.
Alternatively, it you really want to process something in your new 'injected' thread you can:
1) in your 'detoured send' (invoked from main thread's context): pass the data to your thread
and wait untill it finishes processing the data (notice: the main thread is waiting).

Simultaneous Read/Write on a file by two threads (Mutex aren't helping)

I want to use one thread to get fields of packets by using tshark utility (using system () command) whos output is then redirected to a file. This same file needs to be read by another thread simultaneously, so that it can make runtime decisions based on the fields observed in the file.
The problem I am having currently now is even though the first thread is writing to the file, the second thread is unable to read it (It reads NULL from the file). I am not sure why its behaving this way. I thought it might be due to simultaneous access to the same file. I thought of using mutex locks but that would block the reading thread, since the first thread will only end when the program terminates.
Any ideas on how to go about it?
If you are using that file for interprocess communication, you could instead use named pipes or message queues instead. They are much easier to use and don't require synchronization because one thread writes and the other one reads when data is available.
Edit: For inter-thread communication you can simply use shared variables and a conditional variable to signal when some data has been produced (a producer-consumer pattern). Something like:
// thread 1
while(1)
{
// read packet
// write packet to global variable
// signal thread 2
// wait for confirmation of reading
}
// thread 2
while(1)
{
// wait for signal from thread 1
// read from global variable
// signal thread 2 to continue
}
The signal parts can be implemented with conditional variables: pthread_cond_t.

Resources