Use app::Task instead of raw threads on FilterPreview

We can use a thread pool (avoid creating/destroying threads) and we
can continue the same task running when the filter restart (there is
no need to stop/wait and restart, because the filter task keeps
calling the applyStep() function anyway).
This commit is contained in:
David Capello 2023-05-12 10:20:30 -03:00
parent 2369f36322
commit 87075296ed
3 changed files with 25 additions and 25 deletions

2
laf

@ -1 +1 @@
Subproject commit 41476b78d001b82a72cc6556164bc20954d75636 Subproject commit 41822911e4091503bf22071a5ce579c2e03d52eb

View File

@ -21,8 +21,6 @@
#include "ui/message.h" #include "ui/message.h"
#include "ui/widget.h" #include "ui/widget.h"
#include <thread>
namespace app { namespace app {
using namespace ui; using namespace ui;
@ -32,8 +30,6 @@ FilterPreview::FilterPreview(FilterManagerImpl* filterMgr)
: Widget(kGenericWidget) : Widget(kGenericWidget)
, m_filterMgr(filterMgr) , m_filterMgr(filterMgr)
, m_timer(1, this) , m_timer(1, this)
, m_filterThread(nullptr)
, m_filterIsDone(false)
{ {
setVisible(false); setVisible(false);
} }
@ -67,27 +63,32 @@ void FilterPreview::stop()
ASSERT(m_filterMgr); ASSERT(m_filterMgr);
m_filterMgr->end(); m_filterMgr->end();
} }
m_timer.stop();
} }
if (m_filterTask.running()) {
m_timer.stop(); m_filterTask.cancel();
m_filterTask.wait();
if (m_filterThread) {
m_filterThread->join();
m_filterThread.reset();
} }
} }
void FilterPreview::restartPreview() void FilterPreview::restartPreview()
{ {
stop();
std::scoped_lock lock(m_filterMgrMutex); std::scoped_lock lock(m_filterMgrMutex);
// Restart filter, timer, and task if needed (there is no need to
// restart the task if it's already running)
if (m_timer.isRunning()) {
ASSERT(m_filterMgr);
m_filterMgr->end();
}
m_filterMgr->beginForPreview(); m_filterMgr->beginForPreview();
m_filterIsDone = false;
m_timer.start(); m_timer.start();
m_filterThread.reset(
new std::thread([this]{ onFilterThread(); })); if (!m_filterTask.running()) {
m_filterTask.run([this](base::task_token& token){
onFilterTask(token);
});
}
} }
bool FilterPreview::onProcessMessage(Message* msg) bool FilterPreview::onProcessMessage(Message* msg)
@ -112,7 +113,7 @@ bool FilterPreview::onProcessMessage(Message* msg)
std::scoped_lock lock(m_filterMgrMutex); std::scoped_lock lock(m_filterMgrMutex);
if (m_filterMgr) { if (m_filterMgr) {
m_filterMgr->flush(); m_filterMgr->flush();
if (m_filterIsDone) if (m_filterTask.completed())
m_timer.stop(); m_timer.stop();
} }
break; break;
@ -123,14 +124,13 @@ bool FilterPreview::onProcessMessage(Message* msg)
} }
// This is executed in other thread. // This is executed in other thread.
void FilterPreview::onFilterThread() void FilterPreview::onFilterTask(base::task_token& token)
{ {
bool running = true; while (!token.canceled()) {
while (running) {
{ {
std::scoped_lock lock(m_filterMgrMutex); std::scoped_lock lock(m_filterMgrMutex);
m_filterIsDone = !m_filterMgr->applyStep(); if (!m_filterMgr->applyStep())
running = (!m_filterIsDone && m_timer.isRunning()); token.cancel();
} }
base::this_thread::yield(); base::this_thread::yield();
} }

View File

@ -9,11 +9,11 @@
#define APP_COMMANDS_FILTERS_FILTER_PREVIEW_H_INCLUDED #define APP_COMMANDS_FILTERS_FILTER_PREVIEW_H_INCLUDED
#pragma once #pragma once
#include "app/task.h"
#include "ui/timer.h" #include "ui/timer.h"
#include "ui/widget.h" #include "ui/widget.h"
#include <mutex> #include <mutex>
#include <thread>
namespace app { namespace app {
@ -34,12 +34,12 @@ namespace app {
bool onProcessMessage(ui::Message* msg) override; bool onProcessMessage(ui::Message* msg) override;
private: private:
void onFilterThread(); void onFilterTask(base::task_token& token);
FilterManagerImpl* m_filterMgr; FilterManagerImpl* m_filterMgr;
ui::Timer m_timer; ui::Timer m_timer;
std::mutex m_filterMgrMutex; std::mutex m_filterMgrMutex;
std::unique_ptr<std::thread> m_filterThread; app::Task m_filterTask;
bool m_filterIsDone; bool m_filterIsDone;
}; };