Skip to content

Commit

Permalink
refactor(threads): stop card event monitor thread immediately on canc…
Browse files Browse the repository at this point in the history
…el and on critical failure

WE2-672

Signed-off-by: Mart Somermaa <[email protected]>
  • Loading branch information
mrts committed Jun 10, 2022
1 parent 437adea commit e32a24a
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 23 deletions.
7 changes: 6 additions & 1 deletion src/controller/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ QVariantMap makeErrorObject(const QString& errorCode, const QString& errorMessag
void interruptThread(QThread* thread)
{
qDebug() << "Interrupting thread" << uintptr_t(thread);
thread->disconnect();
thread->requestInterruption();
ControllerChildThread::waitForControllerNotify.wakeAll();
}
Expand Down Expand Up @@ -333,6 +332,8 @@ void Controller::onDialogCancel()
{
REQUIRE_NON_NULL(window)

stopCardEventMonitorThread();

qDebug() << "User cancelled";

// Schedule application exit when the UI dialog is destroyed.
Expand All @@ -352,8 +353,11 @@ void Controller::onPinPadCancel()

void Controller::onCriticalFailure(const QString& error)
{
stopCardEventMonitorThread();

qCritical() << "Exiting due to command" << std::string(commandType())
<< "fatal error:" << error;

_result = makeErrorObject(RESP_TECH_ERROR, error);
writeResponseToStdOut(isInStdinMode, _result, commandType());
disposeUI();
Expand All @@ -378,6 +382,7 @@ void Controller::waitForChildThreads()
for (const auto& childThread : childThreads) {
auto thread = childThread.second;
if (thread) {
thread->disconnect();
interruptThread(thread);
// Waiting for PIN input on PIN pad may take a long time, call processEvents() so that
// the UI doesn't freeze.
Expand Down
2 changes: 1 addition & 1 deletion src/controller/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class Controller : public QObject
void saveChildThreadPtrAndConnectFailureFinish(ControllerChildThread* childThread);
void stopCardEventMonitorThread();
void disposeUI();
void exit();
void exit(); // private slot
void waitForChildThreads();
CommandType commandType();

Expand Down
10 changes: 10 additions & 0 deletions src/ui/webeiddialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "ui_dialog.h"

#include <QButtonGroup>
#include <QCloseEvent>
#include <QDesktopServices>
#include <QFile>
#include <QMessageBox>
Expand Down Expand Up @@ -396,6 +397,15 @@ void WebEidDialog::reject()
}
}

void WebEidDialog::closeEvent(QCloseEvent* event)
{
if (closeUnconditionally) {
event->accept();
} else {
WebEidUI::closeEvent(event);
}
}

bool WebEidDialog::event(QEvent* event)
{
if (event->type() == QEvent::LanguageChange) {
Expand Down
11 changes: 2 additions & 9 deletions src/ui/webeiddialog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

#include "ui.hpp"

#include <QCloseEvent>
class QCloseEvent;

// clang-format off
/**
Expand Down Expand Up @@ -76,14 +76,7 @@ class WebEidDialog final : public WebEidUI
bool event(QEvent* event) final;
void reject() final;

void closeEvent(QCloseEvent* event) final
{
if (closeUnconditionally) {
event->accept();
} else {
WebEidUI::closeEvent(event);
}
}
void closeEvent(QCloseEvent* event) final;

void connectOkToCachePinAndEmitSelectedCertificate(const CardCertificateAndPinInfo& certAndPin);

Expand Down
11 changes: 3 additions & 8 deletions tests/mock-ui/mock-ui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,15 @@ class MockUI : public WebEidUI

void onSigningCertificateMismatch() override {}

void onRetry(const RetriableError) override { emit rejected(); }
void onRetry(const RetriableError) override { reject(); }

void onVerifyPinFailed(const electronic_id::VerifyPinFailed::Status, const qint8) override {}

void onSmartCardStatusUpdate(const RetriableError) override
{
emit rejected();
// Schedule invoking Controller::exit().
reject();
emit destroyed();
}

void quit() final
{
// Schedule invoking Controller::exit().
emit destroyed();
}
void quit() final { emit destroyed(); }
};
8 changes: 4 additions & 4 deletions tests/tests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ private slots:
void quit_exits();

private:
void runEventLoopVerifySignalsEmitted(QSignalSpy& actionSpy, bool waitForQuit = true);
void runEventLoopVerifySignalsEmitted(QSignalSpy& actionSpy);
void initGetCert();
void initAuthenticate();
void initCard(bool withSigningScript = true);
Expand All @@ -101,7 +101,7 @@ void WebEidTests::statusUpdate_withUnsupportedCard_hasExpectedStatus()
QSignalSpy statusUpdateSpy(controller.get(), &Controller::statusUpdate);

// act
runEventLoopVerifySignalsEmitted(statusUpdateSpy, false);
runEventLoopVerifySignalsEmitted(statusUpdateSpy);

// assert
const auto statusArgument = qvariant_cast<RetriableError>(statusUpdateSpy.first().at(0));
Expand Down Expand Up @@ -220,7 +220,7 @@ void WebEidTests::quit_exits()
}
}

void WebEidTests::runEventLoopVerifySignalsEmitted(QSignalSpy& actionSpy, bool waitForQuit)
void WebEidTests::runEventLoopVerifySignalsEmitted(QSignalSpy& actionSpy)
{
// Waits until Controller emits quit.
QSignalSpy quitSpy(controller.get(), &Controller::quit);
Expand All @@ -230,7 +230,7 @@ void WebEidTests::runEventLoopVerifySignalsEmitted(QSignalSpy& actionSpy, bool w

// Run the event loop, verify that signals were emitted.
QVERIFY(actionSpy.wait());
if (waitForQuit && quitSpy.count() < 1) {
if (quitSpy.count() < 1) {
QVERIFY(quitSpy.wait());
}
}
Expand Down

0 comments on commit e32a24a

Please sign in to comment.