summaryrefslogtreecommitdiff
path: root/plugins/warp/ui/matches.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/warp/ui/matches.cpp')
-rw-r--r--plugins/warp/ui/matches.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/plugins/warp/ui/matches.cpp b/plugins/warp/ui/matches.cpp
index fad729d6..ed77085a 100644
--- a/plugins/warp/ui/matches.cpp
+++ b/plugins/warp/ui/matches.cpp
@@ -5,6 +5,7 @@
#include <QClipboard>
#include <QFormLayout>
+#include <thread>
#include "theme.h"
#include "warp.h"
@@ -15,6 +16,8 @@ WarpCurrentFunctionWidget::WarpCurrentFunctionWidget(FunctionRef current)
// NOTE: Might be nullptr if the no selected function.
m_current = current;
+ m_logger = new BinaryNinja::Logger("WARP");
+
// Create the QT stuff
QGridLayout *layout = new QGridLayout(this);
layout->setContentsMargins(2, 2, 2, 2);
@@ -110,6 +113,26 @@ void WarpCurrentFunctionWidget::SetCurrentFunction(FunctionRef current)
return;
m_current = current;
m_infoWidget->SetAnalysisFunction(m_current);
+
+ if (current)
+ {
+ // Add the function to the processing list only if we have no already done so.
+ // If a user goes to a function, then navigates away, they do not want to
+ // have us try and send a network request!
+ {
+ std::lock_guard<std::mutex> lock(m_requestMutex);
+ uint64_t funcStart = current->GetStart();
+ if (m_processedFunctions.find(funcStart) == m_processedFunctions.end()) {
+ m_pendingRequests.push_back(current);
+ }
+ }
+ if (!m_requestInProgress.exchange(true)) {
+ BinaryNinja::WorkerPriorityEnqueue([this]() {
+ ProcessPendingFetchRequests();
+ });
+ }
+ }
+
UpdateMatches();
}
@@ -162,3 +185,51 @@ void WarpCurrentFunctionWidget::UpdateMatches()
m_tableWidget->SetFunctions(matches);
}
+
+void WarpCurrentFunctionWidget::ProcessPendingFetchRequests()
+{
+ std::vector<FunctionRef> requests;
+ {
+ std::lock_guard<std::mutex> lock(m_requestMutex);
+ requests = std::move(m_pendingRequests);
+ m_pendingRequests.clear();
+ }
+
+ if (requests.empty()) {
+ m_requestInProgress = false;
+ return;
+ }
+
+ auto start_time = std::chrono::high_resolution_clock::now();
+
+ std::vector<Warp::FunctionGUID> guids;
+ Warp::Ref<Warp::Target> target;
+ for (const auto& func : requests) {
+ // TODO: Need to send multiple requests if there is multiple targets.
+ if (!target)
+ target = Warp::Target::FromPlatform(*func->GetPlatform());
+ if (const auto guid = Warp::GetAnalysisFunctionGUID(*func); guid.has_value())
+ guids.push_back(guid.value());
+ }
+
+ // Actually fetch the data!
+ if (!guids.empty())
+ for (const auto &container: Warp::Container::All())
+ container->FetchFunctions(*target, guids);
+
+ {
+ std::lock_guard<std::mutex> lock(m_requestMutex);
+ for (const auto& func : requests) {
+ m_processedFunctions.insert(func->GetStart());
+ }
+ }
+
+ // TODO: Update the matches, make sure there was stuff added first lol.
+ // TODO: UpdateMatches();
+
+ const auto end_time = std::chrono::high_resolution_clock::now();
+ const std::chrono::duration<double> elapsed_time = end_time - start_time;
+ m_logger->LogDebug("ProcessPendingRequests took %f seconds", elapsed_time.count());
+
+ m_requestInProgress = false;
+}