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

Side by Side Diff: mojo/common/message_pump_mojo.cc

Issue 66193007: Implementation of MessagePump for Mojo. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments and cleanup Created 7 years, 1 month 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 | Annotate | Revision Log
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 #include "mojo/common/message_pump_mojo.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/logging.h"
11 #include "mojo/common/message_pump_mojo_handler.h"
12 #include "mojo/common/scoped_message_pipe.h"
13
14 namespace mojo {
15 namespace common {
16
17 // State needed for one iteration of MojoWaitMany. The first handle and flags
18 // corresponds to that of the control pipe.
19 struct MessagePumpMojo::WaitState {
20 std::vector<MojoHandle> handles;
21 std::vector<MojoWaitFlags> wait_flags;
22 };
23
24 struct MessagePumpMojo::RunState {
25 public:
26 RunState() : should_quit(false) {}
27
28 MojoHandle read_handle() const { return control_pipe.handle_0(); }
29 MojoHandle write_handle() const { return control_pipe.handle_1(); }
30
31 base::TimeTicks delayed_work_time;
32
33 // Used to wake up WaitForWork().
34 ScopedMessagePipe control_pipe;
35
36 bool should_quit;
37 };
38
39 MessagePumpMojo::MessagePumpMojo() : run_state_(NULL) {
40 }
41
42 MessagePumpMojo::~MessagePumpMojo() {
43 }
44
45 void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler,
46 MojoHandle handle,
Ben Goodger (Google) 2013/11/08 21:24:35 mojo::Handle, mojo::WriteMessage etc?
47 MojoWaitFlags wait_flags) {
48 DCHECK(handler);
49 DCHECK_NE(MOJO_HANDLE_INVALID, handle);
50 handlers_[handle].handler = handler;
51 handlers_[handle].wait_flags = wait_flags;
52
53 SignalControlPipe();
54 }
55
56 void MessagePumpMojo::RemoveHandler(MojoHandle handle) {
57 handlers_.erase(handle);
58 SignalControlPipe();
59 }
60
61 void MessagePumpMojo::Run(Delegate* delegate) {
62 RunState* old_state = run_state_;
63 RunState run_state;
64 // TODO: better deal with error handling.
65 CHECK_NE(run_state.control_pipe.handle_0(), MOJO_HANDLE_INVALID);
66 CHECK_NE(run_state.control_pipe.handle_1(), MOJO_HANDLE_INVALID);
67 run_state_ = &run_state;
68 bool more_work_is_plausible = true;
69 for (;;) {
70 const bool block = !more_work_is_plausible;
71 DoInternalWork(block);
72
73 // There isn't a good way to know if there are more handles ready, we assume
74 // not.
75 more_work_is_plausible = false;
76
77 if (run_state.should_quit)
78 break;
79
80 more_work_is_plausible |= delegate->DoWork();
81 if (run_state.should_quit)
82 break;
83
84 more_work_is_plausible |= delegate->DoDelayedWork(
85 &run_state.delayed_work_time);
86 if (run_state.should_quit)
87 break;
88
89 if (more_work_is_plausible)
90 continue;
91
92 more_work_is_plausible = delegate->DoIdleWork();
93 if (run_state.should_quit)
94 break;
95 }
96 run_state_ = old_state;
97 }
98
99 void MessagePumpMojo::Quit() {
100 if (run_state_)
101 run_state_->should_quit = true;
102 }
103
104 void MessagePumpMojo::ScheduleWork() {
105 SignalControlPipe();
106 }
107
108 void MessagePumpMojo::ScheduleDelayedWork(
109 const base::TimeTicks& delayed_work_time) {
110 if (!run_state_)
111 return;
112 run_state_->delayed_work_time = delayed_work_time;
113 SignalControlPipe();
114 }
115
116 void MessagePumpMojo::DoInternalWork(bool block) {
117 MojoDeadline deadline;
118 if (block && !run_state_->delayed_work_time.is_null()) {
119 const base::TimeDelta delta = run_state_->delayed_work_time -
120 base::TimeTicks::Now();
121 deadline = std::max(static_cast<MojoDeadline>(0),
122 static_cast<MojoDeadline>(delta.InMicroseconds()));
123 } else {
124 deadline = 0;
125 }
126 const WaitState wait_state = GetWaitState();
127 const MojoResult result = MojoWaitMany(&wait_state.handles.front(),
128 &wait_state.wait_flags.front(),
129 wait_state.handles.size(),
darin (slow to review) 2013/11/09 00:47:50 nit: win64 build will complain here. need static_c
sky 2013/11/11 15:14:17 Done.
130 deadline);
131 if (result == 0) {
132 // Control pipe was written to.
133 uint32_t num_bytes = 0;
134 MojoReadMessage(run_state_->read_handle(), NULL, &num_bytes, NULL, 0,
135 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD);
136 } else if (result > 0) {
137 const size_t index = static_cast<size_t>(result);
138 DCHECK(handlers_.find(wait_state.handles[index]) != handlers_.end());
139 handlers_[wait_state.handles[index]].handler->OnHandleReady(
140 wait_state.handles[index]);
141 } else {
142 switch (result) {
143 case MOJO_RESULT_INVALID_ARGUMENT:
144 case MOJO_RESULT_FAILED_PRECONDITION:
145 RemoveFirstInvalidHandle(wait_state);
146 break;
147 case MOJO_RESULT_DEADLINE_EXCEEDED:
148 break;
149 default:
150 NOTREACHED();
151 }
152 }
153 }
154
155 void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) {
156 // TODO(sky): deal with control pipe going bad.
157 for (size_t i = 1; i < wait_state.handles.size(); ++i) {
158 const MojoResult result =
159 MojoWait(wait_state.handles[i], wait_state.wait_flags[i], 0);
160 if (result == MOJO_RESULT_INVALID_ARGUMENT ||
161 result == MOJO_RESULT_FAILED_PRECONDITION) {
162 DCHECK(handlers_.find(wait_state.handles[i]) != handlers_.end());
163 MessagePumpMojoHandler* handler =
164 handlers_[wait_state.handles[i]].handler;
165 handlers_.erase(wait_state.handles[i]);
166 handler->OnHandleInvalid(wait_state.handles[i], result);
167 return;
168 } else {
169 DCHECK_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result);
170 }
171 }
172 }
173
174 void MessagePumpMojo::SignalControlPipe() {
175 if (!run_state_)
176 return;
177
178 // TODO(sky): deal with error?
179 MojoWriteMessage(run_state_->write_handle(), NULL, 0, NULL, 0,
180 MOJO_WRITE_MESSAGE_FLAG_NONE);
181 }
182
183 MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState() const {
184 WaitState wait_state;
185 wait_state.handles.push_back(run_state_->write_handle());
186 wait_state.wait_flags.push_back(MOJO_WAIT_FLAG_READABLE);
187
188 for (HandleToHandler::const_iterator i = handlers_.begin();
189 i != handlers_.end(); ++i) {
190 wait_state.handles.push_back(i->first);
191 wait_state.wait_flags.push_back(i->second.wait_flags);
192 }
193 return wait_state;
194 }
195
196 } // namespace common
197 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698