Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(923)

Side by Side Diff: mojo/public/cpp/utility/run_loop.h

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/public/cpp/utility/lib/run_loop.cc ('k') | mojo/public/cpp/utility/run_loop_handler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 <mojo/system/time.h>
9
10 #include <map>
11 #include <queue>
12
13 #include "mojo/public/cpp/bindings/callback.h"
14 #include "mojo/public/cpp/system/handle.h"
15 #include "mojo/public/cpp/system/macros.h"
16 #include "mojo/public/cpp/system/wait_set.h"
17 #include "mojo/public/cpp/utility/run_loop_handler.h"
18
19 namespace mojo {
20
21 // Run loop (a.k.a. message loop): watches handles for signals and calls
22 // handlers when they occur; can also execute posted (delayed) tasks. This class
23 // is not thread-safe.
24 class RunLoop {
25 public:
26 RunLoop();
27 ~RunLoop();
28
29 // Returns the RunLoop for the current thread or null if not yet created.
30 static RunLoop* current();
31
32 // Registers a RunLoopHandler for the specified handle. Returns an |Id|
33 //
34 // The handler's OnHandleReady() method is invoked after one of the signals in
35 // |handle_signals| occurs. Note that the handler remains registered until
36 // explicitly removed or an error occurs.
37 //
38 // The handler's OnHandleError() method is invoked if the deadline elapses, an
39 // error is detected, or the RunLoop is being destroyed (with result
40 // MOJO_RESULT_ABORTED in this case). The handler is automatically
41 // unregistered before calling OnHandleError(), so it will not receive any
42 // further notifications.
43 //
44 // A handler may call AddHandler() again in both OnHandleReady() and
45 // OnHandleError(). Warning: If OnHandleError() was called due to the RunLoop
46 // being destroyed, the newly-added handler's OnHandleError() will also be
47 // called; this may lead to an infinite loop if it again calls AddHandler() ad
48 // infinitum.
49 RunLoopHandler::Id AddHandler(RunLoopHandler* handler,
50 const Handle& handle,
51 MojoHandleSignals handle_signals,
52 MojoDeadline deadline);
53 void RemoveHandler(RunLoopHandler::Id id);
54
55 // Adds a task to be performed after delay has elapsed.
56 void PostDelayedTask(const Closure& task, MojoTimeTicks delay);
57
58 // Runs the loop servicing handles and tasks as they become ready. Returns
59 // when Quit() is invoked, or there are no more handles or tasks.
60 void Run();
61
62 // Runs the loop servicing any handles and tasks that are ready. Does not wait
63 // for handles or tasks to become ready before returning. Returns early if
64 // Quit() is invoked.
65 void RunUntilIdle();
66
67 void Quit();
68
69 // Returns the number of registered handlers. (This is mostly used for
70 // testing.)
71 size_t num_handlers() const { return handlers_.size(); }
72
73 private:
74 static constexpr MojoTimeTicks kInvalidTimeTicks = 0;
75
76 // Contains the information that was passed to |AddHandler()|. These are
77 // stored in |handlers|, which is a map from |RunLoopHandler::Id|s
78 // (generated/returned by |AddHandler()| to |HandlerInfo|s. Each entry in
79 // |handlers_| also has a corresponding entry in |wait_set_| (with cookie the
80 // |RunLoopHandler::Id|).
81 struct HandlerInfo {
82 HandlerInfo(RunLoopHandler* handler,
83 MojoHandleSignals handle_signals,
84 MojoTimeTicks absolute_deadline)
85 : handler(handler),
86 handle_signals(handle_signals),
87 absolute_deadline(absolute_deadline) {}
88
89 RunLoopHandler* handler;
90 MojoHandleSignals handle_signals;
91 // |kInvalidTimeTicks| means forever/no deadline/indefinite.
92 MojoTimeTicks absolute_deadline;
93 };
94 using IdToHandlerInfoMap = std::map<RunLoopHandler::Id, HandlerInfo>;
95
96 // Contains information about a handler with a deadline. These are stored in
97 // the |handler_deadlines_| priority queue (with the earliest/lowest
98 // |RunLoopHandler::Id| at the top). If |id| is not in |handlers_|, then this
99 // deadline is no longer valid (i.e., is stale).
100 struct HandlerDeadlineInfo {
101 HandlerDeadlineInfo(RunLoopHandler::Id id, MojoTimeTicks absolute_deadline)
102 : id(id), absolute_deadline(absolute_deadline) {}
103
104 // Needed to be in a priority queue. Note that |std::priority_queue<>|'s top
105 // is the "greatest" element, whereas we want the earliest.
106 bool operator<(const HandlerDeadlineInfo& other) const {
107 return (absolute_deadline == other.absolute_deadline)
108 ? id < other.id
109 : absolute_deadline > other.absolute_deadline;
110 }
111
112 RunLoopHandler::Id id;
113 MojoTimeTicks absolute_deadline;
114 };
115 using HandlerDeadlineQueue = std::priority_queue<HandlerDeadlineInfo>;
116
117 // Contains information about a task posted using |PostDelayedTask()|. (Even
118 // though tasks are not handlers, we also assign them |RunLoopHandler::Id|s
119 // from the same namespace.) These are stored in the |delayed_tasks_| priority
120 // queue (with the earliest/lowest |RunLoopHandler::Id| at the top).
121 struct DelayedTaskInfo {
122 DelayedTaskInfo(RunLoopHandler::Id id,
123 const Closure& task,
124 MojoTimeTicks absolute_run_time);
125 ~DelayedTaskInfo();
126
127 bool operator<(const DelayedTaskInfo& other) const {
128 return (absolute_run_time == other.absolute_run_time)
129 ? id > other.id
130 : absolute_run_time > other.absolute_run_time;
131 }
132
133 RunLoopHandler::Id id;
134 Closure task;
135 MojoTimeTicks absolute_run_time;
136 };
137 using DelayedTaskQueue = std::priority_queue<DelayedTaskInfo>;
138
139 // Inside of |Run()|/|RunUntilIdle()| (i.e., really in |RunInternal()|), we
140 // have one of these on the stack. |current_run_state_| points to the current
141 // one. (This is needed to handle nested execution.)
142 struct RunState;
143
144 // Helper for |Run()| and |RunUntilIdle()|, which loops and executes delayed
145 // tasks and handlers as handles become "ready". It will if:
146 // - there are no more tasks or registered handlers,
147 // - |Quit()| is called, or
148 // - no work is done in a given iteration if |quit_when_idle| is true.
149 void RunInternal(bool quit_when_idle);
150
151 // Executes one iteration of the run loop. Returns true if the run loop should
152 // continue.
153 bool DoIteration(bool quit_when_idle);
154
155 // Notifies handlers corresponding to the wait results in |results| (which
156 // should not be empty). Returns true if work was done (i.e., any handler was
157 // called).
158 bool NotifyResults(const std::vector<MojoWaitSetResult>& results);
159
160 // Notifies any handlers with a deadline up to |absolute_deadline| was that
161 // their deadline was exceeded. Returns true if work was done (i.e., any
162 // handler was called).
163 bool NotifyHandlersDeadlineExceeded(MojoTimeTicks absolute_deadline);
164
165 // Calculates the absolute deadline (to be turned into a relative deadline)
166 // for the wait set wait. This should only be called if |handlers_| is
167 // nonempty. Returns |kInvalidTimeTicks| for "forever"/indefinite. Sets
168 // |*is_delayed_task| to true if the deadline is for a delayed task.
169 MojoTimeTicks CalculateAbsoluteDeadline(bool* is_delayed_task);
170
171 RunLoopHandler::Id next_id_ = 1u;
172 IdToHandlerInfoMap handlers_;
173 ScopedWaitSetHandle wait_set_;
174 HandlerDeadlineQueue handler_deadlines_;
175 DelayedTaskQueue delayed_tasks_;
176
177 RunState* current_run_state_ = nullptr;
178
179 MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoop);
180 };
181
182 } // namespace mojo
183
184 #endif // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/utility/lib/run_loop.cc ('k') | mojo/public/cpp/utility/run_loop_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698