mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Introduce AsyncTask::runThenCallback
* Fixes #5295 * Introduce a callback approach to AsyncTask instead of entering multiple QEventLoop in the stack. This has additional benefits including not returning to the original stack location and potentially operating on deleted objects (use after free).
This commit is contained in:
parent
fd8d81f517
commit
443b9e4d37
@ -58,6 +58,28 @@ namespace AsyncTask
|
||||
return waitForFuture<FunctionObject>(QtConcurrent::run(task));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a given task then call the defined callback. Prevents event loop blocking and
|
||||
* ensures the validity of the follow-on task through the context. If the context is
|
||||
* deleted, the callback will not be processed preventing use after free errors.
|
||||
*
|
||||
* @param task std::function object to run
|
||||
* @param context QObject responsible for calling this function
|
||||
* @param callback std::function object to run after the task completess
|
||||
*/
|
||||
template <typename FunctionObject, typename FunctionObject2>
|
||||
void runThenCallback(FunctionObject task, QObject* context, FunctionObject2 callback)
|
||||
{
|
||||
typedef QFutureWatcher<typename std::result_of<FunctionObject()>::type> FutureWatcher;
|
||||
auto future = QtConcurrent::run(task);
|
||||
auto watcher = new FutureWatcher(context);
|
||||
QObject::connect(watcher, &QFutureWatcherBase::finished, context, [=]() {
|
||||
watcher->deleteLater();
|
||||
callback(future.result());
|
||||
});
|
||||
watcher->setFuture(future);
|
||||
}
|
||||
|
||||
}; // namespace AsyncTask
|
||||
|
||||
#endif // KEEPASSXC_ASYNCTASK_HPP
|
||||
|
@ -118,13 +118,16 @@ void FileWatcher::checkFileChanged()
|
||||
// Prevent reentrance
|
||||
m_ignoreFileChange = true;
|
||||
|
||||
auto checksum = AsyncTask::runAndWaitForFuture([this]() -> QByteArray { return calculateChecksum(); });
|
||||
if (checksum != m_fileChecksum) {
|
||||
m_fileChecksum = checksum;
|
||||
m_fileChangeDelayTimer.start(0);
|
||||
}
|
||||
AsyncTask::runThenCallback([=] { return calculateChecksum(); },
|
||||
this,
|
||||
[=](QByteArray checksum) {
|
||||
if (checksum != m_fileChecksum) {
|
||||
m_fileChecksum = checksum;
|
||||
m_fileChangeDelayTimer.start(0);
|
||||
}
|
||||
|
||||
m_ignoreFileChange = false;
|
||||
m_ignoreFileChange = false;
|
||||
});
|
||||
}
|
||||
|
||||
QByteArray FileWatcher::calculateChecksum()
|
||||
|
Loading…
Reference in New Issue
Block a user