summaryrefslogtreecommitdiff
path: root/plugins/warp/ui/shared
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-10-12 22:48:41 -0400
committerMason Reed <mason@vector35.com>2025-10-12 22:50:20 -0400
commit253fd4ad2d8095cc3c640c99d75ab3fd1cb7282e (patch)
tree2bb2549d4aa29971143ec013df9cc6971abc6be2 /plugins/warp/ui/shared
parent40f7d40e394657575001a8146d8233f1fc4356fd (diff)
[WARP] Fix misc sidebar navigation / focus event bugs
- Fixed crash related to pending fetch callback for deleted view frame - Fixed focus not being kept for tables in the sidebar, as well as focus in general - Made matched function list navigation require a double click, to fix accidental navigation to other functions
Diffstat (limited to 'plugins/warp/ui/shared')
-rw-r--r--plugins/warp/ui/shared/fetcher.cpp20
-rw-r--r--plugins/warp/ui/shared/fetcher.h26
2 files changed, 31 insertions, 15 deletions
diff --git a/plugins/warp/ui/shared/fetcher.cpp b/plugins/warp/ui/shared/fetcher.cpp
index 1a262878..403d7cdb 100644
--- a/plugins/warp/ui/shared/fetcher.cpp
+++ b/plugins/warp/ui/shared/fetcher.cpp
@@ -24,14 +24,20 @@ std::vector<FunctionRef> WarpFetcher::FlushPendingFunctions()
void WarpFetcher::ExecuteCompletionCallback()
{
- BinaryNinja::ExecuteOnMainThread([this]() {
- // TODO: Holding the mutex here is dangerous!
+ std::vector<std::pair<CallbackId, CompletionCallback>> callbacks;
+ {
std::lock_guard<std::mutex> lock(m_requestMutex);
- m_completionCallbacks.erase(
- std::ranges::remove_if(m_completionCallbacks, [](const auto& cb) { return cb() == RemoveCallback; })
- .begin(),
- m_completionCallbacks.end());
- });
+ callbacks.insert(callbacks.end(), m_completionCallbacks.begin(), m_completionCallbacks.end());
+ }
+
+ std::vector<CallbackId> toRemove = {};
+ for (auto& [id, cb] : callbacks)
+ if (cb() == RemoveCallback)
+ toRemove.push_back(id);
+
+ std::lock_guard<std::mutex> lock(m_requestMutex);
+ for (auto id : toRemove)
+ m_completionCallbacks.erase(id);
}
std::shared_ptr<WarpFetcher> WarpFetcher::Global()
diff --git a/plugins/warp/ui/shared/fetcher.h b/plugins/warp/ui/shared/fetcher.h
index 52d0a0e2..3464ecd4 100644
--- a/plugins/warp/ui/shared/fetcher.h
+++ b/plugins/warp/ui/shared/fetcher.h
@@ -24,11 +24,10 @@ class WarpFetcher
std::mutex m_requestMutex;
std::vector<FunctionRef> m_pendingRequests;
std::unordered_set<Warp::FunctionGUID> m_processedGuids;
-
- // List of callbacks to call when done fetching data, assume that others are using this as well.
- std::vector<std::function<WarpFetchCompletionStatus()>> m_completionCallbacks;
-
public:
+ using CallbackId = uint64_t;
+ using CompletionCallback = std::function<WarpFetchCompletionStatus()>;
+
explicit WarpFetcher();
// The global fetcher instance, this is used for the fetch dialog and the sidebar.
@@ -36,10 +35,18 @@ public:
std::atomic<bool> m_requestInProgress = false;
- void AddCompletionCallback(std::function<WarpFetchCompletionStatus()> cb)
+ [[nodiscard]] CallbackId AddCompletionCallback(CompletionCallback cb)
{
std::lock_guard<std::mutex> lock(m_requestMutex);
- m_completionCallbacks.push_back(std::move(cb));
+ const CallbackId id = m_nextCallbackId++;
+ m_completionCallbacks.emplace(id, std::move(cb));
+ return id;
+ }
+
+ void RemoveCompletionCallback(CallbackId id)
+ {
+ std::lock_guard<std::mutex> lock(m_requestMutex);
+ m_completionCallbacks.erase(id);
}
void AddPendingFunction(const FunctionRef& func);
@@ -49,7 +56,10 @@ public:
void ClearProcessed();
private:
- std::vector<FunctionRef> FlushPendingFunctions();
-
+ // List of callbacks to call when done fetching data, assume that others are using this as well.
+ std::atomic<CallbackId> m_nextCallbackId = 1;
+ std::unordered_map<CallbackId, CompletionCallback> m_completionCallbacks;
void ExecuteCompletionCallback();
+
+ std::vector<FunctionRef> FlushPendingFunctions();
};