From 3acc28cebf9d3ebaa48c564f87c0eb85ed43b74c Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Tue, 31 Oct 2017 21:28:59 +0100 Subject: Postpone error message display if not in GUI thread Calls to report_error() crashed if not called from GUI thread. Fix this by postponing error message display if not in GUI thread. Code that creates a thread which possibly calls report_error() is responsible for calling MainWindow::showErrors() to flush the accumulated messages. Note that there is a race condition in report_error() and get_error_string(). Nevertheless, hitting it should be rather unlikely (two threads producing error messages at the same time) and hopefully it can be fixed rather easily. Signed-off-by: Berthold Stoeger --- desktop-widgets/downloadfromdivecomputer.cpp | 4 ++++ desktop-widgets/mainwindow.cpp | 16 +++++++++++++--- desktop-widgets/mainwindow.h | 4 ++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/desktop-widgets/downloadfromdivecomputer.cpp b/desktop-widgets/downloadfromdivecomputer.cpp index 637f6034d..b875b4a76 100644 --- a/desktop-widgets/downloadfromdivecomputer.cpp +++ b/desktop-widgets/downloadfromdivecomputer.cpp @@ -220,6 +220,10 @@ void DownloadFromDCWidget::updateState(states state) // got an error else if (state == ERROR) { timer->stop(); + + // Show messages that worker thread produced. + MainWindow::instance()->showErrors(); + QMessageBox::critical(this, TITLE_OR_TEXT(tr("Error"), thread.error), QMessageBox::Ok); markChildrenAsEnabled(); progress_bar_text = ""; diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index 95495b663..bcd8f8e6e 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -88,12 +88,22 @@ MainWindow *MainWindow::m_Instance = NULL; extern "C" void showErrorFromC() { + // Show errors only if we are running in the GUI thread. + // If we're not in the GUI thread, let errors accumulate. + if (QThread::currentThread() != QCoreApplication::instance()->thread()) + return; + MainWindow *mainwindow = MainWindow::instance(); - if (mainwindow) { - mainwindow->getNotificationWidget()->showNotification(get_error_string(), KMessageWidget::Error); - } + if (mainwindow) + mainwindow->showErrors(); } +void MainWindow::showErrors() +{ + const char *error = get_error_string(); + if (error && error[0]) + getNotificationWidget()->showNotification(error, KMessageWidget::Error); +} MainWindow::MainWindow() : QMainWindow(), actionNextDive(0), diff --git a/desktop-widgets/mainwindow.h b/desktop-widgets/mainwindow.h index edd3fb0c8..50590aa28 100644 --- a/desktop-widgets/mainwindow.h +++ b/desktop-widgets/mainwindow.h @@ -89,6 +89,10 @@ public: void enableDisableCloudActions(); void setCheckedActionFilterTags(bool checked); + // Shows errors that have accumulated. + // Must be called from GUI thread. + void showErrors(); + private slots: /* file menu action */ -- cgit v1.2.3-70-g09d2