blob: 44a551f3b73144282901d05be6750f38b5d74c0a [file] [log] [blame]
// Copyright 2020 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/ui/lib/escher/flib/fence_queue.h"
#include <lib/syslog/cpp/macros.h>
#include <lib/trace/event.h>
namespace escher {
void FenceQueue::QueueTask(fit::function<void()> task, std::vector<zx::event> fences) {
queue_.emplace_back(std::move(task), std::move(fences));
ProcessQueue();
}
void FenceQueue::ProcessQueue() {
if (queue_.empty() || fence_listener_) {
// The queue is either already being processed or there is nothing in the queue to process.
return;
}
// Handle the next task on the queue.
fence_listener_.emplace(std::move(queue_.front().second));
queue_.front().second.clear();
fence_listener_->WaitReadyAsync([weak = weak_from_this()] {
if (auto locked = weak.lock()) {
// Execute task.
locked->queue_.front().first();
}
// The FenceQueue may have been destroyed in the task. Retry the lock to avoid any weirdness.
if (auto locked = weak.lock()) {
// Keep going until all queued presents have been scheduled.
locked->queue_.pop_front();
locked->fence_listener_.reset();
// After we delete the fence listener, this closure may be deleted. In that case, we should no
// longer access any closed variables.
locked->ProcessQueue();
}
});
}
} // namespace escher