mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-12-01 09:46:09 +03:00
105 lines
3.5 KiB
C++
105 lines
3.5 KiB
C++
// Copyright 2016 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef BASE_TASK_TASK_SCHEDULER_PRIORITY_QUEUE_H_
|
|
#define BASE_TASK_TASK_SCHEDULER_PRIORITY_QUEUE_H_
|
|
|
|
#include <memory>
|
|
#include <queue>
|
|
#include <vector>
|
|
|
|
#include "base/base_export.h"
|
|
#include "base/macros.h"
|
|
#include "base/memory/ref_counted.h"
|
|
#include "base/task/task_scheduler/scheduler_lock.h"
|
|
#include "base/task/task_scheduler/sequence.h"
|
|
#include "base/task/task_scheduler/sequence_sort_key.h"
|
|
|
|
namespace base {
|
|
namespace internal {
|
|
|
|
// A PriorityQueue holds Sequences of Tasks. This class is thread-safe.
|
|
class BASE_EXPORT PriorityQueue {
|
|
public:
|
|
// A Transaction can perform multiple operations atomically on a
|
|
// PriorityQueue. While a Transaction is alive, it is guaranteed that nothing
|
|
// else will access the PriorityQueue.
|
|
//
|
|
// A Worker needs to be able to Peek sequences from both its PriorityQueues
|
|
// (single-threaded and shared) and then Pop the sequence with the highest
|
|
// priority. If the Peek and the Pop are done through the same Transaction, it
|
|
// is guaranteed that the PriorityQueue hasn't changed between the 2
|
|
// operations.
|
|
class BASE_EXPORT Transaction {
|
|
public:
|
|
~Transaction();
|
|
|
|
// Inserts |sequence| in the PriorityQueue with |sequence_sort_key|.
|
|
// Note: |sequence_sort_key| is required as a parameter instead of being
|
|
// extracted from |sequence| in Push() to avoid this Transaction having a
|
|
// lock interdependency with |sequence|.
|
|
void Push(scoped_refptr<Sequence> sequence,
|
|
const SequenceSortKey& sequence_sort_key);
|
|
|
|
// Returns a reference to the SequenceSortKey representing the priority of
|
|
// the highest pending task in this PriorityQueue. The reference becomes
|
|
// invalid the next time that this PriorityQueue is modified.
|
|
// Cannot be called on an empty PriorityQueue.
|
|
const SequenceSortKey& PeekSortKey() const;
|
|
|
|
// Removes and returns the highest priority Sequence in this PriorityQueue.
|
|
// Cannot be called on an empty PriorityQueue.
|
|
scoped_refptr<Sequence> PopSequence();
|
|
|
|
// Returns true if the PriorityQueue is empty.
|
|
bool IsEmpty() const;
|
|
|
|
// Returns the number of Sequences in the PriorityQueue.
|
|
size_t Size() const;
|
|
|
|
private:
|
|
friend class PriorityQueue;
|
|
|
|
explicit Transaction(PriorityQueue* outer_queue);
|
|
|
|
// Holds the lock of |outer_queue_| for the lifetime of this Transaction.
|
|
AutoSchedulerLock auto_lock_;
|
|
|
|
PriorityQueue* const outer_queue_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(Transaction);
|
|
};
|
|
|
|
PriorityQueue();
|
|
|
|
~PriorityQueue();
|
|
|
|
// Begins a Transaction. This method cannot be called on a thread which has an
|
|
// active Transaction unless the last Transaction created on the thread was
|
|
// for the allowed predecessor specified in the constructor of this
|
|
// PriorityQueue.
|
|
std::unique_ptr<Transaction> BeginTransaction();
|
|
|
|
const SchedulerLock* container_lock() const { return &container_lock_; }
|
|
|
|
private:
|
|
// A class combining a Sequence and the SequenceSortKey that determines its
|
|
// position in a PriorityQueue.
|
|
class SequenceAndSortKey;
|
|
|
|
using ContainerType = std::priority_queue<SequenceAndSortKey>;
|
|
|
|
// Synchronizes access to |container_|.
|
|
SchedulerLock container_lock_;
|
|
|
|
ContainerType container_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(PriorityQueue);
|
|
};
|
|
|
|
} // namespace internal
|
|
} // namespace base
|
|
|
|
#endif // BASE_TASK_TASK_SCHEDULER_PRIORITY_QUEUE_H_
|