Qt slot simultaneous disconnect and call from different theads - multithreading

I'm newbie to Qt. I haven't found an answer in a reasonable time and decided to ask here.
I have a thread, let's call it Thread1 with Qt object which have a connected slot. Signal is emitted from the same thread (Thread1).
And I'm disconnecting this slot from another Thread2.
Is this operation thread safe?
Are there any problems, if a signal is emitted and slot is disconnected exactly at the same time?

Just looking at the docs, it looks safe to me:
http://qt-project.org/doc/qt-4.8/qobject.html
Note: All functions in this class are reentrant, but connect(), connect(), disconnect(), and disconnect() are also thread-safe.
http://qt-project.org/doc/qt-4.8/qobject.html#disconnect
Note: This function is thread-safe.
Also make sure that you are using Queued Connections when you are connecting the signal of one thread to the slot of another. The Auto-connect may misbehave (and do direct connection) if both objects happen to be in the same thread during the time of the connection.
Hope that helps.
EDIT: More about Thread Safety:
http://qt-project.org/doc/qt-4.8/threads-reentrancy.html
http://qt-project.org/doc/qt-4.8/threads-qobject.html

Related

Safe way to handle closure of sockets managed by epoll

Using epoll_wait to manage multiple connections using multiple threads, there is a risk trying to release custom data associated with a closed socket.
Consider the following scenario, where T is the custom data :
Data is received,
Because of 1, thread A deblocks from epoll_wait and processes the event (access T)
At same time, another thread B, wants to close the connection
Thread B can't assume that T can be safely deleted, eventhough the call to close will immediatly remove the socket from the epoll.
I had the following standard idea :
Maintain a variable within T that gets incremented each time a call to write/read returns EAGAIN, and gets decremented each time the socket is ready.
When close is called, wait for that variable to go down to zero before deleting T.
The issue I experienced is that if close is called, epoll_wait does not return an indication of a cancellation of previous calls to arm the socket.
Anybody had this same problem ? How did you managed to overcome it ?
At least three possible ways here:
Do not use threads, simple and clean, and usually works.
Have a dedicated thread do all file descriptor polling and publish events to a pool of worker threads that do actual I/O and processing.
Have one epoll(7) instance per thread, so threads manage non-intersecting sets of descriptors, with the exception of maybe the listening socket(s) to get these sets populated, and some control mechanism like eventfd(2), or self-pipe(2) to be able to shutdown the whole rig cleanly.
Hope this helps.
After many research, I found this recent and remarkable article :
http://lwn.net/Articles/520012/
Basically it acknowledge the issue I am describing and speaks about a possible future patch to Linux kernel that allows to extend the epoll API in a way that solves the issue.
The extension bring a new command called : EPOLL_CTL_DISABLE.
When it is issued, and by means of return value, the calling thread will know if some other thread has just been deblocked from epoll_wait upon same socket.
This can help know the safe moment of closure and release of custom data.

Global variable declaration in Qt

I have made a Gui thread and a QTcpSocket thread in Qt.I want to access data
from QTcpSocket thread to Gui thread.How to solve it?
Do i need to declare some global variable and how?
The easiest way is to communicate via signal-slot connections. There is one QObject in each thread. The sending object has a signal, which is connected to the slot of the receiving object in the other thread.
In this setup, you make sure that the objects on both ends of the connections are configured to live in the correct threads. You might need to call QObject::moveToThread(). QObject also has a property where you can get the current thread (for debugging purposes in this case).
Then just establish the signal-slot connection as usual. Since both objects are in different threads, when the signal is triggered, a slot invocation event will be placed in the event loop of the receiving flag. This is explained in the Qt documentation, look for Qt::QueuedConnection.
The QTcpSocket is created from the gui thread.
So at that point the gui thread has a pointer to the socket object.
It then creates a connection between a slot in the gui and a signal in the socket.
In the socket object whenever you get data you simply emit a signal containing the data, which will be picked up by the gui thread.
You can pass any Qt type eg QString, QByteArray (or a raw pointer), through a signal/slot very efficiently. The details if signals between threads are also handled automatically.

How to interrupt a thread performing a blocking socket connect?

I have some code that spawns a pthread that attempts to maintain a socket connection to a remote host. If the connection is ever lost, it attempts to reconnect using a blocking connect() call on its socket. Since the code runs in a separate thread, I don't really care about the fact that it uses the synchronous socket API.
That is, until it comes time for my application to exit. I would like to perform some semblance of an orderly shutdown, so I use thread synchronization primitives to wake up the thread and signal for it to exit, then perform a pthread_join() on the thread to wait for it to complete. This works great, unless the thread is in the middle of a connect() call when I command the shutdown. In that case, I have to wait for the connect to time out, which could be a long time. This makes the application appear to take a long time to shut down.
What I would like to do is to interrupt the call to connect() in some way. After the call returns, the thread will notice my exit signal and shut down cleanly. Since connect() is a system call, I thought that I might be able to intentionally interrupt it using a signal (thus making the call return EINTR), but I'm not sure if this is a robust method in a POSIX threads environment.
Does anyone have any recommendations on how to do this, either using signals or via some other method? As a note, the connect() call is down in some library code that I cannot modify, so changing to a non-blocking socket is not an option.
Try to close() the socket to interrupt the connect(). I'm not sure, but I think it will work at least on Linux. Of course, be careful to synchronize properly such that you only ever close() this socket once, or a second close() could theoretically close an unrelated file descriptor that was just opened.
EDIT: shutdown() might be more appropriate because it does not actually close the socket.
Alternatively, you might want to take a look at pthread_cancel() and pthread_kill(). However, I don't see a way to use these two without a race condition.
I advise that you abandon the multithreaded-server approach and instead go event-driven, for example by using epoll for event notification. This way you can avoid all these very basic problems that become very hard with threads, like proper shutdown. You are free to at any time do anything you want, e.g. safely close sockets and never hear from them again.
On the other hand, if in your worker thread you do a non-blocking connect() and get notified via epoll_pwait() (or ppoll() or pselect(); note the p), you may be able to avoid race conditions associated with signals.

Why are slots being called from the main thread?

I have a Qt application that has two threads: the main thread that handles the GUI and a second thread that manages network connections. Here is the thread code:
void thread::run()
{
QTcpServer server;
server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect()));
//...
}
When I put a breakpoint at the start of OnConnect() and debug the application, it announces that OnConnect() is being called from the main thread!
How can I have OnConnect() run in the same thread as the QTcpServer?
To give a more thorough answer, look a little deeper into how signal-slot connections and thread contexts interact. Basically, for more connections (auto-connect), the slot will be directly called if both the emitter and the receiver are in the same thread context, otherwise it will be a queued connection, and the slot will be run in the thread context of the object that contains the slot. In this case, it must be queued, which implies that your thread is part of the main application's thread context, not its own. This is reinforced by the documentation Qt provides for an overview of its threading, where it states that the QThread instance is "owned" by the thread context that created it, not the thread context that it represents. This means you have three main choices:
You can use moveToThread() to move the thread into its own context. Note that this may cause problems when deleting the thread unless you move it back to the context where it will be destroyed, and this can only be done in the source-thread context, so it would have to be done before the run function exited.
You can treat the QThread instance as a handle to the thread, not as being part of the thread itself. If you need things done in the context of the new thread, create a different object to handle those, and instantiate them in the context of the new thread (inside the run function). This is what I would recommend.
Force a direct connection. This means you would need to ensure the code running in the slot is thread-safe, ignoring Qt's built-in methods of making those functions thread-safe. This is what you have done.
It seems like the problem was that I wasn't passing Qt::DirectConnection as the last parameter of connect().
After adding that, it worked.

Is SetEvent atomic?

Is it safe to have 2 or more threads call the Win32 API's SetEvent on the same event handler not being protected by a critical section?
It's safe, but remember that if one thread Sets it, and another thread Sets it at the same time, you're not going to get two notifications, just one; since the 2nd one changed it from True to...True. If you're worried about this, use Semaphores instead.
Assuming you have multiple threads waiting on the same event, running the same code.
If your code doesnt clear the event until its done processing, you effectively have a CS. Since the event remains signaled until it is cleared(aka not autoreset), having multiple threads signal the does nothing except spin the CPU.
If your code clears it at the begining of processing or the event is autorset, then you would have multiple threads running the same function, which is unsafe if these threads share anything.
there are no restrictions on calling SetEvent from multiple threads.

Resources