Qt:死锁的QMessageBox不在信号处理中出现

时间:2018-08-04 22:51:55

标签: qt

我最后添加了UPD。

我想做什么

我有一个执行此操作的主GUI线程:

void main(int argc, char** argv)
{
    QApplication app(argc, argv);
    MainWindow mainWindow; // an engine thread is started here
    mainWindow.show();
    app.exec(); // here the GUI thread enters the event processing loop
}

我连接了一个信号和一个插槽以处理具有BlockingQueuedConnection类型的GUI线程(是MainWindow)中的通知:

connect(&warningSignalEmitter, SIGNAL(popuped(QString)),
    this, SLOT(onPopupWarning(QString)), Qt::BlockingQueuedConnection);

如果发出信号,则GUI线程将显示一个MessageBox:

void MainWindow::onPopupWarning(QString message)
{
    QMessageBox::warning(nullptr, "Warning", message);
}

我有一个引擎线程创建OpenGL上下文并执行渲染循环。 QOpenGLDebugLogger在此线程中用以下代码初始化:

logger = new QOpenGLDebugLogger();
logger->initialize();

connect(logger, SIGNAL(messageLogged(QOpenGLDebugMessage)),
    this, SLOT(glDebugMessageLogged(QOpenGLDebugMessage)),
    Qt::ConnectionType::DirectConnection);

logger->startLogging(QOpenGLDebugLogger::LoggingMode::SynchronousLogging);

连接类型为DirectConnection,因此如果引擎线程调用OpenGL函数时发生错误,引擎线程将进入插槽,即:

void Engine::glDebugMessageLogged(const QOpenGLDebugMessage &debugMessage)
{
    emit warningSignalEmitter.popuped(debugMessage.message());
}

引擎线程被锁定在此处,直到GUI线程退出MainWindow :: onPopupWarning。

因此,如果OpenGL函数调用中发生错误,我想看到一个消息框。

我的问题

如果我只是在引擎代码中某处发出 emission warningSignalEmitter.popuped(debugMessage.message())信号,则一切正常,我看到一个MessageBox,引擎线程被锁定,无法发出信号并将GUI线程锁定在onPopupWarning插槽中,直到我在消息框上单击“确定”为止。

当显示消息框时,我看到了此正常堆栈跟踪。

BUT 如果在OpenGL函数调用中发生错误,则引擎线程成功进入glDebugMessageLogged插槽(由于直接连接)并发出信号。之后,它会按预期锁定。 GUI线程进入onPopupWarning插槽,但是当它调用QMessageBox :: warning时,消息框没有出现,GUI线程已被锁定在此调用中,我无法单击OK,并且继续执行。

我在此死锁中看到了这种异常的堆栈跟踪。

可能是什么?

UPD

我已经报告了这个问题,现在我想这是一个错误。您可以在https://bugreports.qt.io/browse/QTBUG-69780

处下载演示该问题的源代码。

0 个答案:

没有答案