OLD | NEW |
| (Empty) |
1 // Copyright 2013 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 MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_ | |
6 #define MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_ | |
7 | |
8 #include <map> | |
9 #include <queue> | |
10 | |
11 #include "mojo/public/cpp/bindings/callback.h" | |
12 #include "mojo/public/cpp/system/core.h" | |
13 | |
14 namespace mojo { | |
15 | |
16 class RunLoopHandler; | |
17 | |
18 class RunLoop { | |
19 public: | |
20 RunLoop(); | |
21 ~RunLoop(); | |
22 | |
23 // Sets up state needed for RunLoop. This must be invoked before creating a | |
24 // RunLoop. | |
25 static void SetUp(); | |
26 | |
27 // Cleans state created by Setup(). | |
28 static void TearDown(); | |
29 | |
30 // Returns the RunLoop for the current thread. Returns null if not yet | |
31 // created. | |
32 static RunLoop* current(); | |
33 | |
34 // Registers a RunLoopHandler for the specified handle. Only one handler can | |
35 // be registered for a specified handle. | |
36 void AddHandler(RunLoopHandler* handler, | |
37 const Handle& handle, | |
38 MojoHandleSignals handle_signals, | |
39 MojoDeadline deadline); | |
40 void RemoveHandler(const Handle& handle); | |
41 bool HasHandler(const Handle& handle) const; | |
42 | |
43 // Runs the loop servicing handles and tasks as they are ready. This returns | |
44 // when Quit() is invoked, or there are no more handles nor tasks. | |
45 void Run(); | |
46 | |
47 // Runs the loop servicing any handles and tasks that are ready. Does not wait | |
48 // for handles or tasks to become ready before returning. Returns early if | |
49 // Quit() is invoked. | |
50 void RunUntilIdle(); | |
51 | |
52 void Quit(); | |
53 | |
54 // Adds a task to be performed after delay has elapsed. Must be posted to the | |
55 // current thread's RunLoop. | |
56 void PostDelayedTask(const Closure& task, MojoTimeTicks delay); | |
57 | |
58 private: | |
59 struct RunState; | |
60 struct WaitState; | |
61 | |
62 // Contains the data needed to track a request to AddHandler(). | |
63 struct HandlerData { | |
64 HandlerData() | |
65 : handler(nullptr), | |
66 handle_signals(MOJO_HANDLE_SIGNAL_NONE), | |
67 deadline(0), | |
68 id(0) {} | |
69 | |
70 RunLoopHandler* handler; | |
71 MojoHandleSignals handle_signals; | |
72 MojoTimeTicks deadline; | |
73 // See description of |RunLoop::next_handler_id_| for details. | |
74 int id; | |
75 }; | |
76 | |
77 typedef std::map<Handle, HandlerData> HandleToHandlerData; | |
78 | |
79 // Used for NotifyHandlers to specify whether HandlerData's |deadline| | |
80 // should be checked prior to notifying. | |
81 enum CheckDeadline { CHECK_DEADLINE, IGNORE_DEADLINE }; | |
82 | |
83 // Mode of operation of the run loop. | |
84 enum RunMode { UNTIL_EMPTY, UNTIL_IDLE }; | |
85 | |
86 // Runs the loop servicing any handles and tasks that are ready. If | |
87 // |run_mode| is |UNTIL_IDLE|, does not wait for handles or tasks to become | |
88 // ready before returning. Returns early if Quit() is invoked. | |
89 void RunInternal(RunMode run_mode); | |
90 | |
91 // Do one unit of delayed work, if eligible. Returns true is a task was run. | |
92 bool DoDelayedWork(); | |
93 | |
94 // Waits for a handle to be ready or until the next task must be run. Returns | |
95 // after servicing at least one handle (or there are no more handles) unless | |
96 // a task must be run or |non_blocking| is true, in which case it will also | |
97 // return if no task is registered and servicing at least one handle would | |
98 // require blocking. Returns true if a RunLoopHandler was notified. | |
99 bool Wait(bool non_blocking); | |
100 | |
101 // Notifies handlers of |error|. If |check| == CHECK_DEADLINE, this will | |
102 // only notify handlers whose deadline has expired and skips the rest. | |
103 // Returns true if a RunLoopHandler was notified. | |
104 bool NotifyHandlers(MojoResult error, CheckDeadline check); | |
105 | |
106 // Returns the state needed to pass to WaitMany(). | |
107 WaitState GetWaitState(bool non_blocking) const; | |
108 | |
109 HandleToHandlerData handler_data_; | |
110 | |
111 // If non-null we're running (inside Run()). Member references a value on the | |
112 // stack. | |
113 RunState* run_state_; | |
114 | |
115 // An ever increasing value assigned to each HandlerData::id. Used to detect | |
116 // uniqueness while notifying. That is, while notifying expired timers we copy | |
117 // |handler_data_| and only notify handlers whose id match. If the id does not | |
118 // match it means the handler was removed then added so that we shouldn't | |
119 // notify it. | |
120 int next_handler_id_; | |
121 | |
122 struct PendingTask { | |
123 PendingTask(const Closure& task, | |
124 MojoTimeTicks runtime, | |
125 uint64_t sequence_number); | |
126 ~PendingTask(); | |
127 | |
128 bool operator<(const PendingTask& other) const; | |
129 | |
130 Closure task; | |
131 MojoTimeTicks run_time; | |
132 uint64_t sequence_number; | |
133 }; | |
134 // An ever increasing sequence number attached to each pending task in order | |
135 // to preserve relative order of tasks posted at the 'same' time. | |
136 uint64_t next_sequence_number_; | |
137 typedef std::priority_queue<PendingTask> DelayedTaskQueue; | |
138 DelayedTaskQueue delayed_tasks_; | |
139 | |
140 MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoop); | |
141 }; | |
142 | |
143 } // namespace mojo | |
144 | |
145 #endif // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_ | |
OLD | NEW |