| Index: third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
 | 
| diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
 | 
| index dee99194ecc13e1a591d5dd47d570827b46de8b4..f56bb3615cd85453575210e901c239369a867bc6 100644
 | 
| --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
 | 
| +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
 | 
| @@ -28,6 +28,32 @@ namespace internal {
 | 
|  class WorkQueue;
 | 
|  class WorkQueueSets;
 | 
|  
 | 
| +// TaskQueueImpl has four main queues:
 | 
| +//
 | 
| +// Immediate (non-delayed) tasks:
 | 
| +//    immediate_incoming_queue - PostTask enqueues tasks here
 | 
| +//    immediate_work_queue
 | 
| +//
 | 
| +// Delayed tasks
 | 
| +//    delayed_incoming_queue - PostDelayedTask enqueues tasks here
 | 
| +//    delayed_work_queue
 | 
| +//
 | 
| +// The immediate_incoming_queue can be accessed from any thread, the other
 | 
| +// queues are main-thread only. To reduce the overhead of locking,
 | 
| +// immediate_work_queue is swapped with immediate_incoming_queue when
 | 
| +// immediate_work_queue becomes empty.
 | 
| +//
 | 
| +// Delayed tasks are initially posted to delayed_incoming_queue and a wakeup
 | 
| +// is scheduled with the TimeDomain.  When the delay has elapsed, the TimeDomain
 | 
| +// calls UpdateDelayedWorkQueue and ready delayed tasks are moved into the
 | 
| +// delayed_work_queue.  Note the EnqueueOrder (used for ordering) for a delayed
 | 
| +// task is not set until it's moved into the delayed_work_queue.
 | 
| +//
 | 
| +// TaskQueueImpl uses the WorkQueueSets and the TaskQueueSelector to implement
 | 
| +// prioritization. Task selection is done by the TaskQueueSelector and when a
 | 
| +// queue is selected, it round-robins between the immediate_work_queue and
 | 
| +// delayed_work_queue.  The reason for this is we want to make sure delayed
 | 
| +// tasks (normally the most common type) don't starve out immediate work.
 | 
|  class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
 | 
|   public:
 | 
|    TaskQueueImpl(TaskQueueManager* task_queue_manager,
 | 
| @@ -52,6 +78,10 @@ class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
 | 
|           bool nestable,
 | 
|           EnqueueOrder enqueue_order);
 | 
|  
 | 
| +    // Create a fake Task based on the handle, suitable for using as a search
 | 
| +    // key.
 | 
| +    static Task CreateFakeTaskFromHandle(const TaskHandle& handle);
 | 
| +
 | 
|      EnqueueOrder enqueue_order() const {
 | 
|  #ifndef NDEBUG
 | 
|        DCHECK(enqueue_order_set_);
 | 
| @@ -71,13 +101,33 @@ class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
 | 
|      bool enqueue_order_set() const { return enqueue_order_set_; }
 | 
|  #endif
 | 
|  
 | 
| +    using ComparatorFn = bool (*)(const Task&, const Task&);
 | 
| +
 | 
| +    // Tasks are ordered by |delayed_run_time| smallest first then and by
 | 
| +    // |sequence_num| in case of a tie.
 | 
| +    class DelayedRunTimeComparator {
 | 
| +     public:
 | 
| +      bool operator()(const Task& a, const Task& b) const;
 | 
| +    };
 | 
| +
 | 
| +    // Tasks are ordered by |enqueue_order_| smallest first.
 | 
| +    static bool EnqueueOrderComparatorFn(const TaskQueueImpl::Task& a,
 | 
| +                                         const TaskQueueImpl::Task& b);
 | 
| +
 | 
| +    // Tasks are ordered by |delayed_run_time| smallest first then and by
 | 
| +    // |sequence_num| in case of a tie.
 | 
| +    static bool DelayedRunTimeComparatorFn(const TaskQueueImpl::Task& a,
 | 
| +                                           const TaskQueueImpl::Task& b);
 | 
| +
 | 
|     private:
 | 
|  #ifndef NDEBUG
 | 
|      bool enqueue_order_set_;
 | 
|  #endif
 | 
| -    // Similar to sequence number, but the |enqueue_order| is set by
 | 
| -    // EnqueueTasksLocked and is not initially defined for delayed tasks until
 | 
| -    // they are enqueued on the |immediate_incoming_queue_|.
 | 
| +    // Similar to sequence number, but ultimately the |enqueue_order_| is what
 | 
| +    // the scheduler uses for task ordering. For immediate tasks |enqueue_order|
 | 
| +    // is set when posted, but for delayed tasks it's not defined until they are
 | 
| +    // enqueued on the |delayed_work_queue_|. This is because otherwise delayed
 | 
| +    // tasks could run before an immediate task posted after the delayed task.
 | 
|      EnqueueOrder enqueue_order_;
 | 
|    };
 | 
|  
 | 
| @@ -90,7 +140,11 @@ class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
 | 
|    bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
 | 
|                                    const base::Closure& task,
 | 
|                                    base::TimeDelta delay) override;
 | 
| -
 | 
| +  TaskHandle PostCancellableDelayedTask(
 | 
| +      const tracked_objects::Location& from_here,
 | 
| +      const base::Closure& task,
 | 
| +      base::TimeDelta delay) override;
 | 
| +  bool CancelTask(const TaskHandle& handle) override;
 | 
|    void SetQueueEnabled(bool enabled) override;
 | 
|    bool IsQueueEnabled() const override;
 | 
|    bool IsEmpty() const override;
 | 
| @@ -108,6 +162,8 @@ class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
 | 
|    TimeDomain* GetTimeDomain() const override;
 | 
|    void SetBlameContext(base::trace_event::BlameContext* blame_context) override;
 | 
|  
 | 
| +  bool IsTaskPending(const TaskHandle& handle) const;
 | 
| +
 | 
|    void UpdateImmediateWorkQueue(bool should_trigger_wakeup,
 | 
|                                  const Task* previous_task);
 | 
|    void UpdateDelayedWorkQueue(LazyNow* lazy_now,
 | 
| @@ -162,6 +218,13 @@ class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
 | 
|   private:
 | 
|    friend class WorkQueue;
 | 
|  
 | 
| +  // Note both DelayedRunTimeQueue and ComparatorQueue are sets for fast task
 | 
| +  // cancellation. Typically queue sizes are well under 200 so the overhead of
 | 
| +  // std::set vs std::priority_queue and std::queue is lost in the noise of
 | 
| +  // everything else.
 | 
| +  using DelayedRunTimeQueue = std::set<Task, Task::DelayedRunTimeComparator>;
 | 
| +  using ComparatorQueue = std::set<Task, Task::ComparatorFn>;
 | 
| +
 | 
|    enum class TaskType {
 | 
|      NORMAL,
 | 
|      NON_NESTABLE,
 | 
| @@ -180,7 +243,7 @@ class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
 | 
|      PumpPolicy pump_policy;
 | 
|      TimeDomain* time_domain;
 | 
|  
 | 
| -    std::queue<Task> immediate_incoming_queue;
 | 
| +    ComparatorQueue immediate_incoming_queue;
 | 
|    };
 | 
|  
 | 
|    struct MainThreadOnly {
 | 
| @@ -199,7 +262,7 @@ class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
 | 
|  
 | 
|      std::unique_ptr<WorkQueue> delayed_work_queue;
 | 
|      std::unique_ptr<WorkQueue> immediate_work_queue;
 | 
| -    std::priority_queue<Task> delayed_incoming_queue;
 | 
| +    DelayedRunTimeQueue delayed_incoming_queue;
 | 
|      base::ObserverList<base::MessageLoop::TaskObserver> task_observers;
 | 
|      size_t set_index;
 | 
|      bool is_enabled;
 | 
| @@ -258,9 +321,9 @@ class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
 | 
|    void PushOntoImmediateIncomingQueueLocked(Task pending_task);
 | 
|  
 | 
|    void TraceQueueSize(bool is_locked) const;
 | 
| -  static void QueueAsValueInto(const std::queue<Task>& queue,
 | 
| +  static void QueueAsValueInto(const ComparatorQueue& queue,
 | 
|                                 base::trace_event::TracedValue* state);
 | 
| -  static void QueueAsValueInto(const std::priority_queue<Task>& queue,
 | 
| +  static void QueueAsValueInto(const DelayedRunTimeQueue& queue,
 | 
|                                 base::trace_event::TracedValue* state);
 | 
|    static void TaskAsValueInto(const Task& task,
 | 
|                                base::trace_event::TracedValue* state);
 | 
| 
 |