Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / content / renderer / scheduler / task_queue_manager.h
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
6 #define CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
7
8 #include "base/atomic_sequence_num.h"
9 #include "base/debug/task_annotator.h"
10 #include "base/macros.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/pending_task.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/synchronization/lock.h"
15 #include "base/threading/thread_checker.h"
16 #include "content/common/content_export.h"
17
18 namespace content {
19 namespace internal {
20 class TaskQueue;
21 }
22 class TaskQueueSelector;
23
24 // The task queue manager provides N task queues and a selector interface for
25 // choosing which task queue to service next. Each task queue consists of two
26 // sub queues:
27 //
28 // 1. Incoming task queue. Tasks that are posted get immediately appended here.
29 //    When a task is appended into an empty incoming queue, the task manager
30 //    work function (DoWork) is scheduled to run on the main task runner.
31 //
32 // 2. Work queue. If a work queue is empty when DoWork() is entered, tasks from
33 //    the incoming task queue (if any) are moved here. The work queues are
34 //    registered with the selector as input to the scheduling decision.
35 //
36 class CONTENT_EXPORT TaskQueueManager {
37  public:
38   // Create a task queue manager with |task_queue_count| task queues.
39   // |main_task_runner| identifies the thread on which where the tasks are
40   // eventually run. |selector| is used to choose which task queue to service.
41   // It should outlive this class.
42   TaskQueueManager(size_t task_queue_count,
43                    scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
44                    TaskQueueSelector* selector);
45   ~TaskQueueManager();
46
47   // Returns the task runner which targets the queue selected by |queue_index|.
48   scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerForQueue(
49       size_t queue_index) const;
50
51   // If |auto_pump| is false, tasks posted to the given incoming queue will not
52   // be automatically scheduled for execution or transferred to the work queue.
53   // Instead, the selector should call PumpQueue() when necessary to bring in
54   // new tasks for execution.
55   void SetAutoPump(size_t queue_index, bool auto_pump);
56
57   // Reloads new tasks from the incoming queue for |queue_index| into the work
58   // queue, regardless of whether the work queue is empty or not. After this,
59   // this function ensures that the tasks in the work queue, if any, are
60   // scheduled for execution.
61   //
62   // This function only needs to be called if automatic pumping is disabled
63   // for |queue_index|. See |SetQueueAutoPump|. By default automatic pumping is
64   // enabled for all queues.
65   void PumpQueue(size_t queue_index);
66
67   // Returns true if there no tasks in either the work or incoming task queue
68   // identified by |queue_index|. Note that this function involves taking a
69   // lock, so calling it has some overhead.
70   bool IsQueueEmpty(size_t queue_index) const;
71
72  private:
73   friend class internal::TaskQueue;
74
75   // Called by the task queue to register a new pending task and allocate a
76   // sequence number for it.
77   void DidQueueTask(base::PendingTask* pending_task);
78
79   // Post a task to call DoWork() on the main task runner.
80   void PostDoWorkOnMainRunner();
81
82   // Use the selector to choose a pending task and run it.
83   void DoWork();
84
85   // Reloads any empty work queues which have automatic pumping enabled.
86   // Returns true if any work queue has tasks after doing this.
87   bool UpdateWorkQueues();
88
89   // Runs a single task from the work queue designated by |queue_index|. The
90   // queue must not be empty.
91   void RunTaskFromWorkQueue(size_t queue_index);
92
93   bool RunsTasksOnCurrentThread() const;
94   bool PostDelayedTask(const tracked_objects::Location& from_here,
95                        const base::Closure& task,
96                        base::TimeDelta delay);
97   bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
98                                   const base::Closure& task,
99                                   base::TimeDelta delay);
100   internal::TaskQueue* Queue(size_t queue_index) const;
101
102   std::vector<scoped_refptr<internal::TaskQueue>> queues_;
103   base::AtomicSequenceNumber task_sequence_num_;
104   base::debug::TaskAnnotator task_annotator_;
105
106   base::ThreadChecker main_thread_checker_;
107   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
108   TaskQueueSelector* selector_;
109
110   base::WeakPtr<TaskQueueManager> task_queue_manager_weak_ptr_;
111   base::WeakPtrFactory<TaskQueueManager> weak_factory_;
112
113   DISALLOW_COPY_AND_ASSIGN(TaskQueueManager);
114 };
115
116 }  // namespace content
117
118 #endif  // CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_