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
35 changes: 26 additions & 9 deletions plugins/warp/ui/matches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <thread>
#include <QGridLayout>
#include <QHeaderView>
#include <QtConcurrent/QtConcurrent>

WarpCurrentFunctionWidget::WarpCurrentFunctionWidget(QWidget* parent) : QWidget(parent)
{
Expand Down Expand Up @@ -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]() {
Comment thread
emesare marked this conversation as resolved.
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);
});
}
}
Expand Down
1 change: 1 addition & 0 deletions plugins/warp/ui/shared/fetcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}