QSerialport is blocked in QThread - multithreading

I was trying to read the serial output from a thread. The Serial port is opened in main program and passed the QSerialPort variable to thread. The thread is called using signals and slot mechanism like following code.
connect(m_serial, &QSerialPort::readyRead, this, &MySerialPort::startReadingThread);
Then I called serial.readAll() function in thread and print the received data into logs. But after some time the serialport get blocked and not printing any data.
QByteArray message = MySerialPort::m_serial->readAll();
qDebug() << message;
Can anyone tell me why the serialport get blocked.

Related

How to unblock a QThread running a pcsc call?

I have a Qt application that connects to a card reader using various pcsc implementations under GNU/Linux, MacOS, and Windows. All communication with the card runs in a worker thread.
In one scenario, the user starts an operation requiring communication with the card via a card reader. The card reader has a keyboard and during the authentication procedure the user must enter their PIN on the reader's keyboard.
This operation is implemented by a call to SCardControl() (see e.g. the Microsoft documentation). As long as the user is working with the reader, the call to SCardControl() does not terminate and the worker thread is blocked by it.
At this point, the user might decide to close the application while the operation is still pending. Closing the application at this point causes the application to crash (on Linux with signal SIGABRT) because:
The worker thread is blocked waiting for SCardControl() to return.
The main thread cannot stop the blocked thread: neither quit() nor terminate() cause the thread to finish.
When the application is exited, the QThread object for the worker thread is destroyed and, since the thread is still running state, it throws a signal to indicate an error.
I have tried several solutions.
Subclass QThread and create a worker thread which calls setTerminationEnabled(true); to allow termination through QThread::terminate(). This does not work on MacOS: when QThread is destroyed, the thread is still in a running state and the signal SIGABRT is emitted.
Handle signal SIGABRT on shutdown and ignore it. This did not seem to be a good idea but I wanted to try it out before discarding it. After ignoring signal SIGABRT, a signal SIGSEGV is received and the application crashes. I had adapted the approach described here.
Try to unblock the thread by sending a command to the card reader from the main thread. I tried SCardCancel(), SCardDisconnect() and SCardReleaseContext() but none of these commands has any effect on the blocked thread.
I find it quite strange that it is not possible to cleanly shutdown an application when a thread is blocked on some function call, but all the solutions I have tried have not worked and I have run out of ideas. Did I overlook something? Does anybody have any useful hint?
EDIT
I looked into the Qt source code for QThread and found out that on Unix-like platforms QThread::terminate() uses pthread_cancel() internally. But apparently pthread_cancel() does not work / does nothing on Darwin, see e.g. here and here.
So, maybe I will really have to go with the option of showing a dialog to the user asking to remove the card from the reader.
Cleanly shutting down a thread is not possible from outside if it is blocked in a call. You can, however, prevent user from quitting the application before the operation has completed.
void MainWindow::closeEvent(QCloseEvent *closeEvent) {
if (workerBlocked) closeEvent->ignore();
}
In addition, you can show a dialog telling the user the operation has to be completed first.
Also, if possible, you can let the window close but keep the application alive until the operation is complete by setting qApp->setQuitOnLastWindowClosed(false);
The problem boils down to the fact that a QThread object isn't destructible while the associated thread is running. Usually, it would a print statement like this to the debug output:
QThread: Destroyed while thread is still running
Don't agonize over trying to get SCardControl to return so that the worker thread can be quit safely (since it doesn't return as long as the user is interacting with the reader). Instead, You can follow this answer to destruct the QThread object in a safe manner with a minimum amount of changes to your current implementation.
Here is an example that shows what I mean:
#include <QtWidgets>
//a thread that can be destroyed at any time
//see http://stackoverflow.com/a/25230470
class SafeThread : public QThread{
using QThread::run;
public:
explicit SafeThread(QObject* parent= nullptr):QThread(parent){}
~SafeThread(){ quit(); wait(); }
};
//worker QObject class
class Worker : public QObject {
Q_OBJECT
public:
explicit Worker(QObject* parent = nullptr):QObject(parent){}
~Worker(){}
Q_SLOT void doBlockingWork() {
emit started();
//the sleep call blocks the worker thread for 10 seconds!
//consider it a mock call to the SCardControl function
QThread::sleep(10);
emit finished();
}
Q_SIGNAL void started();
Q_SIGNAL void finished();
};
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
//setup worker thread and QObject
Worker worker;
SafeThread thread;
worker.moveToThread(&thread);
thread.start();
//setup GUI components
QWidget w;
QVBoxLayout layout(&w);
QPushButton button("start working");
QLabel status("idle");
layout.addWidget(&button);
layout.addWidget(&status);
//connect signals/slots
QObject::connect(&worker, &Worker::started, &status,
[&status]{ status.setText("working. . .");} );
QObject::connect(&worker, &Worker::finished, &status,
[&status]{ status.setText("idle");} );
QObject::connect(&button, &QPushButton::clicked, &worker, &Worker::doBlockingWork);
w.show();
return a.exec();
}
#include "main.moc"
Notice that the SafeThread's destructor makes sure to wait() until the associated thread has finished execution. And only afterwards, the main thread can proceed to call QThread's destructor.

C++ Multithreading Run function on main thread

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.

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.

How do I "disengage" from `accept` on a blocking socket when signalled from another thread?

I am in the same situation as this guy, but I don't quite understand the answer.
The problem:
Thread 1 calls accept on a socket, which is blocking.
Thread 2 calls close on this socket.
Thread 1 continues blocking. I want it to return from accept.
The solution:
what you should do is send a signal to the thread which is blocked in
accept. This will give it EINTR and it can cleanly disengage - and
then close the socket. Don't close it from a thread other than the one
using it.
I don't get what to do here -- when the signal is received in Thread 1, accept is already blocking, and will continue to block after the signal handler has finished.
What does the answer really mean I should do?
If the Thread 1 signal handler can do something which will cause accept to return immediately, why can't Thread 2 do the same without signals?
Is there another way to do this without signals? I don't want to increase the caveats on the library.
Instead of blocking in accept(), block in select(), poll(), or one of the similar calls that allows you to wait for activity on multiple file descriptors and use the "self-pipe trick". All of the file descriptors passed to select() should be in non-blocking mode. One of the file descriptors should be the server socket that you use with accept(); if that one becomes readable then you should go ahead and call accept() and it will not block. In addition to that one, create a pipe(), set it to non-blocking, and check for the read side becoming readable. Instead of calling close() on the server socket in the other thread, send a byte of data to the first thread on the write end of the pipe. The actual byte value doesn't matter; the purpose is simply to wake up the first thread. When select() indicates that the pipe is readable, read() and ignore the data from the pipe, close() the server socket, and stop waiting for new connections.
The accept() call will return with error code EINTR if a signal is caught before a connection is accepted. So check the return value and error code then close the socket accordingly.
If you wish to avoid the signal mechanism altogether, use select() to determine if there are any incoming connections ready to be accepted before calling accept(). The select() call can be made with a timeout so that you can recover and respond to abort conditions.
I usually call select() with a timeout of 1000 to 3000 milliseconds from a while loop that checks for an exit/abort condition. If select() returns with a ready descriptor I call accept() otherwise I either loop around and block again on select() or exit if requested.
Call shutdown() from Thread 2. accept will return with "invalid argument".
This seems to work but the documentation doesn't really explain its operation across threads -- it just seems to work -- so if someone can clarify this, I'll accept that as an answer.
Just close the listening socket, and handle the resulting error or exception from accept().
I believe signals can be used without increasing "the caveats on the library". Consider the following:
#include <pthread.h>
#include <signal.h>
#include <stddef.h>
static pthread_t thread;
static volatile sig_atomic_t sigCount;
/**
* Executes a concurrent task. Called by `pthread_create()`..
*/
static void* startTask(void* arg)
{
for (;;) {
// calls to `select()`, `accept()`, `read()`, etc.
}
return NULL;
}
/**
* Starts concurrent task. Doesn't return until the task completes.
*/
void start()
{
(void)pthread_create(&thread, NULL, startTask, NULL);
(void)pthread_join(thread);
}
static void noop(const int sig)
{
sigCount++;
}
/**
* Stops concurrent task. Causes `start()` to return.
*/
void stop()
{
struct sigaction oldAction;
struct sigaction newAction;
(void)sigemptyset(&newAction.sa_mask);
newAction.sa_flags = 0;
newAction.sa_handler = noop;
(void)sigaction(SIGTERM, &newAction, &oldAction);
(void)pthread_kill(thread, SIGTERM); // system calls return with EINTR
(void)sigaction(SIGTERM, &oldAction, NULL); // restores previous handling
if (sigCount > 1) // externally-generated SIGTERM was received
oldAction.sa_handler(SIGTERM); // call previous handler
sigCount = 0;
}
This has the following advantages:
It doesn't require anything special in the task code other than normal EINTR handling; consequently, it makes reasoning about resource leakage easier than using pthread_cancel(), pthread_cleanup_push(), pthread_cleanup_pop(), and pthread_setcancelstate().
It doesn't require any additional resources (e.g. a pipe).
It can be enhanced to support multiple concurrent tasks.
It's fairly boilerplate.
It might even compile. :-)

winapi threads take time to initialise before message passing works?

I have a main program that creates the threads in order:
ThreadB then
ThreadA (which is passed ThreadB's ID)
using the CreateThread function.
Thread A sends a message to Thread B using PostThreadMessage.
B gets the message using GetMessage.
The problem I am having is that PostThreadMessage blocks randomly the first time it is called and never returns, some times the program funs fine, other times I run the program and it blocks with 0 CPU usage at the first postthreadmessage. However if I add Sleep(10) to ThreadA before the first PostThreadMessage, I never seem to encouter this problem.
What am I missing about the timing of threads and messages?
You cannot send a message to a thread until it has a message queue. Message queues are not created until that thread calls a function such as GetMessage or PeekMessage. What your sleep does is delay the sending thread long enough that the receiving thread has called GetMessage and set up its message queue.
Incidentally, I strongly recommend against using PostThreadMessage as the messages can get lost. It is better to create a message-only window (with a parent of HWND_MESSAGE) on the receiving thread and send messages to that instead.
To add to Anthony Williams correct answer, the code I use to deal with this looks like. I have a class similar to MyThread...
void MyThread::Start()
{
m_hResumeMain = CreateEvent(NULL,FALSE,FALSE,NULL);
m_hThread = CreateThread(NULL,0,ThreadProc,this,0,&m_dwThreadId);
WaitForSingleObject(m_hResumeMain,INFINITE);
CloseHandle(m_hResumeMain);
m_hResumeMain=0;
}
DWORD MyThread::ThreadProc(LPVOID pv)
{
MyThread* self = (MyThread*)pv;
return self->ThreadProc();
}
DWORD MyThread::ThreadProc()
{
MSG msg;
// Create the thread message queue
PeekMessage(&msg,0,0,0,PM_NOREMOVE);
// Resume the main thread
SetEvent(m_hResumeMain);
while(GetMessage(&msg,0,0,0)>0){
if(msg.hwnd){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
DoThreadMessage(&msg);
}
}
return 0;
}
The crux of the issue is you ultimately cannot rely on a Sleep to guarantee that the worker thread is sufficiently initialized. Plus, in general there is usually some mimimal amount of work a worker thread needs to have done before the launching thread should be allowed to resume. So create an event object before creating the thread, wait for it on the main thread and signal it on the worker thread once the initialization is done.

Resources