summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/warp/ui/matches.cpp35
-rw-r--r--plugins/warp/ui/shared/fetcher.cpp1
2 files changed, 27 insertions, 9 deletions
diff --git a/plugins/warp/ui/matches.cpp b/plugins/warp/ui/matches.cpp
index 918312fd..2af17383 100644
--- a/plugins/warp/ui/matches.cpp
+++ b/plugins/warp/ui/matches.cpp
@@ -8,6 +8,7 @@
#include <thread>
#include <QGridLayout>
#include <QHeaderView>
+#include <QtConcurrent/QtConcurrent>
WarpCurrentFunctionWidget::WarpCurrentFunctionWidget(QWidget* parent) : QWidget(parent)
{
@@ -151,22 +152,38 @@ void WarpCurrentFunctionWidget::SetCurrentFunction(FunctionRef current)
m_current = current;
m_infoWidget->SetAnalysisFunction(m_current);
- // If we have a fetcher we should also let it know to try and fetch the possible functions from the containers.
+ // If we have a fetcher, we should also let it know to try and fetch the possible functions from the containers.
if (current && m_fetcher)
{
m_fetcher->AddPendingFunction(current);
-
- // TODO: Automatically fetch the function, I need to figure out how to make this debounce correctly so that all
- // requests are processed in line.
if (!m_fetcher->m_requestInProgress.exchange(true))
{
- BinaryNinja::WorkerPriorityEnqueue([this]() {
- QMetaObject::invokeMethod(this, [this] { m_spinner->show(); }, Qt::QueuedConnection);
+ // Don't block the UI thread when fetching, also unlike other cases where we reach for QtConcurrent::run we
+ // do not use a watcher to tie the future to the widget's lifetime, this is because network requests can
+ // take a long time, and we want to avoid blocking the UI thread in the widget destructor. Instead of
+ // ensuring the widget is alive, we just use a weak pointer that can tell us when it (self) has been
+ // destructed.
+ auto future = QtConcurrent::run([self = QPointer(this), current, fetcher = m_fetcher]() {
+ if (!self)
+ return;
+ QMetaObject::invokeMethod(
+ self,
+ [self] {
+ if (self)
+ self->m_spinner->show();
+ },
+ Qt::QueuedConnection);
BinaryNinja::Ref bgTask = new BinaryNinja::BackgroundTask("Fetching WARP Functions...", true);
- const auto allowedTags = GetAllowedTagsFromView(m_current->GetView());
- m_fetcher->FetchPendingFunctions(allowedTags);
+ const auto allowedTags = GetAllowedTagsFromView(current->GetView());
+ fetcher->FetchPendingFunctions(allowedTags);
bgTask->Finish();
- QMetaObject::invokeMethod(this, [this] { m_spinner->hide(); }, Qt::QueuedConnection);
+ QMetaObject::invokeMethod(
+ self,
+ [self] {
+ if (self)
+ self->m_spinner->hide();
+ },
+ Qt::QueuedConnection);
});
}
}
diff --git a/plugins/warp/ui/shared/fetcher.cpp b/plugins/warp/ui/shared/fetcher.cpp
index f5aa626a..daa3fece 100644
--- a/plugins/warp/ui/shared/fetcher.cpp
+++ b/plugins/warp/ui/shared/fetcher.cpp
@@ -113,6 +113,7 @@ void WarpFetcher::FetchPendingFunctions(const std::vector<Warp::SourceTag>& allo
void WarpFetcher::ClearProcessed()
{
+ std::lock_guard<std::mutex> lock(m_requestMutex);
m_logger->LogInfoF("Clearing {} processed functions from cache...", m_processedGuids.size());
m_processedGuids.clear();
}