Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions src/mainwindow/mainwindow-async.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,13 @@ struct NODISCARD MainWindow::AsyncBase
{
public:
const std::shared_ptr<ProgressCounter> progressCounter;
const CancelDispositionEnum cancelDisposition = CancelDispositionEnum::Allow;

public:
explicit AsyncBase(std::shared_ptr<ProgressCounter> pc)
explicit AsyncBase(std::shared_ptr<ProgressCounter> pc,
const CancelDispositionEnum cancelDisposition_)
: progressCounter{std::move(pc)}
, cancelDisposition{cancelDisposition_}
{
if (!progressCounter) {
throw std::invalid_argument("pc");
Expand All @@ -285,12 +288,16 @@ struct NODISCARD MainWindow::AsyncBase
NODISCARD PollResultEnum poll() { return poll(std::chrono::milliseconds{0}); }
void request_cancel();
NODISCARD bool requested_cancel() const;
NODISCARD bool is_allowed_to_cancel() const;
};

MainWindow::AsyncBase::~AsyncBase() = default;

void MainWindow::AsyncBase::request_cancel()
{
if (!is_allowed_to_cancel()) {
return;
}
progressCounter->requestCancel();
virt_request_cancel();
}
Expand All @@ -300,6 +307,11 @@ bool MainWindow::AsyncBase::requested_cancel() const
return progressCounter->requestedCancel();
}

bool MainWindow::AsyncBase::is_allowed_to_cancel() const
{
return cancelDisposition == CancelDispositionEnum::Allow;
}

MainWindow::AsyncTask::AsyncTask(QObject *parent)
: QObject(parent)
{}
Expand Down Expand Up @@ -337,7 +349,7 @@ void MainWindow::AsyncTask::tick()
return;
}

if (m_task->poll() != PollResultEnum::Finished) {
if (deref(m_task).poll() != PollResultEnum::Finished) {
return;
}

Expand All @@ -347,7 +359,12 @@ void MainWindow::AsyncTask::tick()

void MainWindow::AsyncTask::request_cancel()
{
m_task->request_cancel();
deref(m_task).request_cancel();
}

bool MainWindow::AsyncTask::is_allowed_to_cancel() const
{
return deref(m_task).is_allowed_to_cancel();
}

void MainWindow::AsyncTask::reset()
Expand Down Expand Up @@ -403,7 +420,7 @@ struct NODISCARD MainWindow::AsyncHelper : public AsyncBase
UniqueStorage ps,
const QString &dialogText,
const CancelDispositionEnum allow_cancel)
: AsyncBase{std::move(pc)}
: AsyncBase{std::move(pc), allow_cancel}
, mainWindow{mw}
, fileName{name}
, pDevice(std::move(pd))
Expand Down
31 changes: 27 additions & 4 deletions src/mainwindow/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1556,18 +1556,41 @@ bool MainWindow::eventFilter(QObject *const obj, QEvent *const event)

void MainWindow::closeEvent(QCloseEvent *const event)
{
// REVISIT: wait and see if we're actually exiting first?
writeSettings();
qInfo() << MM_SOURCE_LOCATION().function_name();

if (m_asyncTask) {
// first check avoids prompting to save while saving.
if (!m_asyncTask.is_allowed_to_cancel()) {
qInfo() << "Note: Ignoring close request because the current async task cannot be canceled.";
event->ignore();
return;
}
}

if (!maybeSave()) {
event->ignore();
return;
}

if (m_asyncTask) {
qInfo() << "Attempting to async task for faster shutdown";
m_progressDlg->reject();
// second check is in case we just scheduled a save.
if (!m_asyncTask.is_allowed_to_cancel()) {
qInfo() << "Note: Ignoring close request because the scheduled async task cannot be canceled.";
event->ignore();
return;
}
if (m_asyncTask.isWorking()) {
qInfo() << "Attempting to cancel async task for faster shutdown";
m_asyncTask.request_cancel();
}
if (auto dlg = m_progressDlg.get()) {
qInfo() << "Attempting to reject the progress dialog for faster shutdown";
dlg->reject();
}
}

writeSettings();

event->accept();
}

Expand Down
1 change: 1 addition & 0 deletions src/mainwindow/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ class NODISCARD_QOBJECT MainWindow final : public QMainWindow
void begin(std::unique_ptr<AsyncBase> task);
void tick();
void request_cancel();
NODISCARD bool is_allowed_to_cancel() const;

private:
void reset();
Expand Down
Loading