I am moving some sockets from main thread to worker thread and processing readyRead()
, close()
, write()
etc. on the new thread. Rarely I see below dangerous warning:
"QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread"
Usually the execution after this warning results in undefined behaviour (crash / uncaught exception / normal).
Have checked all the signal/slot to the socket and they seem proper. From my experience, usually the above warning will be frequent or quick if there is any coding irregularity.
Now I am suspecting if moveToThread()
does its job as expected or not! Because from QEvent documentation a QEvent::ThreadChange
is raised as the last event on the current thread during this function call.
The object is moved to another thread. This is the last event sent to this object in the previous thread. See
QObject::moveToThread()
1.
1 AQEvent::ThreadChange
event is sent to this object just before the thread affinity is changed. You can handle this event to perform any special processing.
In my code, I am not checking for this event. Rather I assume that, once the moveToThread()
is finished, the thread affinity is changed and the new "signal/slot" on the object is guaranteed on the new thread.
Question:
- Is it safe to move the sockets to another thread?
- Will
moveToThread()
assure that the signals on that object are also moved to the new thread just after this function? - How should it be designed to assure no threading irregularity with Sockets?
BTW, in the latest Qt debugger it lands on following code segment:
// qsocketnotifier.cpp
if (Q_UNLIKELY(thread() != QThread::currentThread())) {
qWarning("QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread");
return;
}
Below is the stack frame for the main thread:
Below is the stack frame for the worker thread, which halts on the logging: