#ifndef BASE_TASK_SEQUENCE_MANAGER_WAKE_UP_QUEUE_H_
#define BASE_TASK_SEQUENCE_MANAGER_WAKE_UP_QUEUE_H_
#include <optional>
#include "base/base_export.h"
#include "base/check.h"
#include "base/containers/intrusive_heap.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/task/common/lazy_now.h"
#include "base/task/sequence_manager/task_queue_impl.h"
#include "base/time/time.h"
#include "base/values.h"
namespace base {
namespace sequence_manager {
class EnqueueOrder;
namespace internal {
class AssociatedThreadId;
class SequenceManagerImpl;
class TaskQueueImpl;
class BASE_EXPORT WakeUpQueue {
public:
WakeUpQueue(const WakeUpQueue&) = delete;
WakeUpQueue& operator=(const WakeUpQueue&) = delete;
virtual ~WakeUpQueue();
std::optional<WakeUp> GetNextDelayedWakeUp() const;
Value::Dict AsValue(TimeTicks now) const;
bool empty() const { return wake_up_queue_.empty(); }
void MoveReadyDelayedTasksToWorkQueues(LazyNow* lazy_now,
EnqueueOrder enqueue_order);
void SetNextWakeUpForQueue(internal::TaskQueueImpl* queue,
LazyNow* lazy_now,
std::optional<WakeUp> wake_up);
virtual void UnregisterQueue(internal::TaskQueueImpl* queue) = 0;
void RemoveAllCanceledDelayedTasksFromFront(LazyNow* lazy_now);
protected:
explicit WakeUpQueue(
scoped_refptr<const internal::AssociatedThreadId> associated_thread);
virtual void OnNextWakeUpChanged(LazyNow* lazy_now,
std::optional<WakeUp> next_wake_up) = 0;
virtual const char* GetName() const = 0;
private:
friend class MockWakeUpQueue;
struct ScheduledWakeUp {
WakeUp wake_up;
RAW_PTR_EXCLUSION internal::TaskQueueImpl* queue = nullptr;
bool operator>(const ScheduledWakeUp& other) const {
return wake_up.latest_time() > other.wake_up.latest_time();
}
void SetHeapHandle(HeapHandle handle) {
DCHECK(handle.IsValid());
queue->set_heap_handle(handle);
}
void ClearHeapHandle() {
DCHECK(queue->heap_handle().IsValid());
queue->set_heap_handle(HeapHandle());
}
HeapHandle GetHeapHandle() const { return queue->heap_handle(); }
};
IntrusiveHeap<ScheduledWakeUp, std::greater<>> wake_up_queue_;
const scoped_refptr<const internal::AssociatedThreadId> associated_thread_;
};
class BASE_EXPORT DefaultWakeUpQueue : public WakeUpQueue {
public:
DefaultWakeUpQueue(
scoped_refptr<internal::AssociatedThreadId> associated_thread,
internal::SequenceManagerImpl* sequence_manager);
~DefaultWakeUpQueue() override;
private:
void OnNextWakeUpChanged(LazyNow* lazy_now,
std::optional<WakeUp> wake_up) override;
const char* GetName() const override;
void UnregisterQueue(internal::TaskQueueImpl* queue) override;
raw_ptr<internal::SequenceManagerImpl> sequence_manager_;
};
class BASE_EXPORT NonWakingWakeUpQueue : public WakeUpQueue {
public:
explicit NonWakingWakeUpQueue(
scoped_refptr<internal::AssociatedThreadId> associated_thread);
~NonWakingWakeUpQueue() override;
private:
void OnNextWakeUpChanged(LazyNow* lazy_now,
std::optional<WakeUp> wake_up) override;
const char* GetName() const override;
void UnregisterQueue(internal::TaskQueueImpl* queue) override;
};
}
}
}
#endif