Unix signals and QCharts cause application blocking
-
Perform a write test on the socketpair. Each time, 278 (0~277) pieces of data are written and then frozen.
int cnt = 0; while (true) { char a = 1; ::write(mSocketFd[0], &a, sizeof(a)); qDebug() << __FUNCTION__ << cnt++; }
debug output:
PanelDriver 0 PanelDriver 1 PanelDriver 2 PanelDriver 3 ... ... ... PanelDriver 273 PanelDriver 274 PanelDriver 275 PanelDriver 276 PanelDriver 277
-
It may not be caused by the socket write buffer being full. It seems that after the socket was written, the activate() signal was not triggered, causing the socket to be unable to read in time, and then causing the socket write buffer to be full.
However, I have already processed all events in timerEvent, and I don't know why there is still a freeze. More strangely, from the debug output information, it can be seen that the exception occurred at the moment the timerEvent returned.
void PanelDriver::unixSignalHandler(int) { qDebug() << __FUNCTION__ << 0; char a = 1; ::write(mSocketFd[0], &a, sizeof(a)); mBufferCounter++; qDebug() << __FUNCTION__ << 1 << mBufferCounter; } void PanelDriver::qtSignalHandler() { mSocketNotifier->setEnabled(false); char tmp; ::read(mSocketFd[1], &tmp, sizeof(tmp)); mBufferCounter--; qDebug() << __FUNCTION__ << mBufferCounter; mSocketNotifier->setEnabled(true); } void JCDemoDriver::timerEvent(QTimerEvent *event) { if (event->timerId() != mTimerId) { qDebug() << __FUNCTION__ << __LINE__; QWidget::timerEvent(event); return; } static int cnt = 0; #if 0 qDebug() << __FUNCTION__ << cnt++; #else label->setText(QString::number(cnt++)); #endif int ms = 0; do { QThread::msleep(1); QCoreApplication::processEvents(); if (ms % 10 == 0) qDebug() << __FUNCTION__ << ms; } while ((ms++) < 100); qDebug() << __FUNCTION__ << QTime::currentTime(); }
debug output:
timerEvent 0 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 10 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 20 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 30 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 40 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 50 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 60 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 70 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 80 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 90 unixSignalHandler 0 unixSignalHandler 1 1 qtSignalHandler 0 timerEvent 100 timerEvent QTime("11:12:00.360") unixSignalHandler 0 unixSignalHandler 1 1 unixSignalHandler 0 unixSignalHandler 1 2 unixSignalHandler 0 unixSignalHandler 1 3 unixSignalHandler 0 unixSignalHandler 1 4 unixSignalHandler 0 unixSignalHandler 1 5 unixSignalHandler 0 unixSignalHandler 1 6 unixSignalHandler 0 unixSignalHandler 1 7 unixSignalHandler 0 unixSignalHandler 1 8 unixSignalHandler 0 unixSignalHandler 1 9 unixSignalHandler 0 unixSignalHandler 1 10 ... ... ... ... ... ... ... unixSignalHandler 0 unixSignalHandler 1 273 unixSignalHandler 0 unixSignalHandler 1 274 unixSignalHandler 0 unixSignalHandler 1 275 unixSignalHandler 0 unixSignalHandler 1 276 unixSignalHandler 0 unixSignalHandler 1 277 unixSignalHandler 0 unixSignalHandler 1 278 unixSignalHandler 0 unixSignalHandler 0 unixSignalHandler 0 unixSignalHandler 0
-
-
-
@tovax said in Unix signals and QCharts cause application blocking:
It can be determined that the freezing of the application has nothing to do with the reading and writing of the socket. Because just setting the unix signal handler can also cause freezing.
After making unixSignalHandler() reentrant, socket write blocking is likely to be the main cause of freezing. I am testing and will update the github code in 12 hours.
-
@tovax said in Unix signals and QCharts cause application blocking:
socket write blocking is likely to be the main cause of freezing
Sockets do have a "backlog queue" for writes issued, just like for file writes. However you are only talking about maybe 5 separate 1 byte writes, I'd be surprised if that hit it. Unless there is a "special case" for needing the read from the first write before further writes go through.
-
@JonB said in Unix signals and QCharts cause application blocking:
@tovax said in Unix signals and QCharts cause application blocking:
socket write blocking is likely to be the main cause of freezing
Sockets do have a "backlog queue" for writes issued, just like for file writes. However you are only talking about maybe 5 separate 1 byte writes, I'd be surprised if that hit it. Unless there is a "special case" for needing the read from the first write before further writes go through.
From the test results of these two days, I also believe that socket write blocking is not the real cause, but a result of other issues.
-
@tovax said in Unix signals and QCharts cause application blocking:
@JonB
After 15 hours of testing, running socketpair in the thread pool will not freeze the application (git commit id: 74d295).Although using thread pools can temporarily solve this problem, I still don't know what the real reason is. Why does socketpair cause the application to freeze in the main thread. My feeling is that when a timerEvent returns, due to the fact that the sleep time is greater than the timing period, the application's handling of other events (such as unixSignalHandler) has any particularity. But I don't know how to test this assumption.
The reason I'm assuming this is that when executing QCoreApplication:: processEvents() while sleeping in timerEvent, there seems to be no problem. When socketpair is running in the main thread, the following test code in timerEvent)() can produce completely different results.#if 1 /* Will not freeze */ int ms = 0; do { QThread::msleep(1); QCoreApplication::processEvents(); if (ms % 20 == 0) qDebug() << __FUNCTION__ << ms; } while ((ms++) < 200); #else /* Causes the application to freeze */ QThread::msleep(200); #endif