| // Copyright 2026 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/developer/debug/zxdb/client/async_task_tree.h" |
| |
| #include "src/developer/debug/zxdb/client/thread.h" |
| |
| namespace zxdb { |
| |
| AsyncTaskTree::AsyncTaskTree(Delegate* delegate) : delegate_(delegate), weak_factory_(this) {} |
| |
| AsyncTaskTree::~AsyncTaskTree() = default; |
| |
| fxl::WeakPtr<AsyncTaskTree> AsyncTaskTree::GetWeakPtr() { return weak_factory_.GetWeakPtr(); } |
| |
| void AsyncTaskTree::Sync(Thread* thread, |
| fit::callback<void(const Err&, const Frame* const frame)> callback) { |
| FX_DCHECK(thread); |
| if (!thread->GetStack().has_all_frames()) { |
| thread->GetStack().SyncFrames({}, [this, cb = std::move(callback)](const Err& err) mutable { |
| if (err.has_error()) { |
| cb(err, nullptr); |
| return; |
| } |
| delegate_->SyncAsyncTasks(this, std::move(cb)); |
| }); |
| } else { |
| // Stack is already synchronized. |
| delegate_->SyncAsyncTasks(this, std::move(callback)); |
| } |
| } |
| |
| void AsyncTaskTree::ForEach(fit::function<void(const TaskEntry&)> fn) const { |
| std::vector<TaskEntry> stack; |
| |
| // Initialize the stack with the root tasks. |
| for (const auto& root_task : GetRootTasks()) { |
| stack.push_back({.task = root_task, .depth = 0}); |
| } |
| |
| while (!stack.empty()) { |
| TaskEntry entry = stack.back(); |
| stack.pop_back(); |
| |
| fn(entry); |
| |
| // Children are added at the end (they will be processed next). |
| const auto& children = entry.task.GetChildren(); |
| for (const auto& child : children) { |
| stack.push_back({.task = child, .depth = entry.depth + 1}); |
| } |
| } |
| } |
| |
| void AsyncTaskTree::SetTasks(std::vector<std::unique_ptr<AsyncTask>> tasks) { |
| root_tasks_ = std::move(tasks); |
| } |
| |
| std::vector<AsyncTask::Ref> AsyncTaskTree::GetRootTasks() const { |
| std::vector<AsyncTask::Ref> ret; |
| ret.reserve(root_tasks_.size()); |
| for (const auto& root_task : root_tasks_) { |
| ret.push_back(*root_task); |
| } |
| return ret; |
| } |
| |
| void AsyncTaskTree::ClearTasks() { root_tasks_.clear(); } |
| |
| } // namespace zxdb |