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

Side by Side Diff: mojo/public/utility/run_loop.cc

Issue 134253004: Mojo: AsyncWaiter and mojo/public/environment (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add missing files Created 6 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/public/utility/run_loop.h" 5 #include "mojo/public/utility/run_loop.h"
6 6
7 #include <assert.h> 7 #include <assert.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <vector> 10 #include <vector>
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 } 96 }
97 97
98 void RunLoop::Run() { 98 void RunLoop::Run() {
99 assert(current() == this); 99 assert(current() == this);
100 // We don't currently support nesting. 100 // We don't currently support nesting.
101 assert(!run_state_); 101 assert(!run_state_);
102 RunState* old_state = run_state_; 102 RunState* old_state = run_state_;
103 RunState run_state; 103 RunState run_state;
104 run_state_ = &run_state; 104 run_state_ = &run_state;
105 while (!run_state.should_quit) 105 while (!run_state.should_quit)
106 Wait(); 106 Wait(false);
107 run_state_ = old_state; 107 run_state_ = old_state;
108 } 108 }
109 109
110 void RunLoop::RunUntilIdle() {
111 assert(current() == this);
112 // We don't currently support nesting.
113 assert(!run_state_);
114 RunState* old_state = run_state_;
115 RunState run_state;
116 run_state_ = &run_state;
117 while (!run_state.should_quit) {
118 if (!Wait(true))
119 break;
120 }
121 run_state_ = old_state;
122 }
123
110 void RunLoop::Quit() { 124 void RunLoop::Quit() {
111 assert(current() == this); 125 assert(current() == this);
112 if (run_state_) 126 if (run_state_)
113 run_state_->should_quit = true; 127 run_state_->should_quit = true;
114 } 128 }
115 129
116 void RunLoop::Wait() { 130 bool RunLoop::Wait(bool non_blocking) {
117 const WaitState wait_state = GetWaitState(); 131 const WaitState wait_state = GetWaitState(non_blocking);
118 if (wait_state.handles.empty()) { 132 if (wait_state.handles.empty()) {
119 Quit(); 133 Quit();
120 return; 134 return false;
121 } 135 }
122 136
123 const MojoResult result = 137 const MojoResult result =
124 WaitMany(wait_state.handles, wait_state.wait_flags, wait_state.deadline); 138 WaitMany(wait_state.handles, wait_state.wait_flags, wait_state.deadline);
125 if (result >= 0) { 139 if (result >= 0) {
126 const size_t index = static_cast<size_t>(result); 140 const size_t index = static_cast<size_t>(result);
127 assert(handler_data_.find(wait_state.handles[index]) != 141 assert(handler_data_.find(wait_state.handles[index]) !=
128 handler_data_.end()); 142 handler_data_.end());
129 handler_data_[wait_state.handles[index]].handler->OnHandleReady( 143 handler_data_[wait_state.handles[index]].handler->OnHandleReady(
130 wait_state.handles[index]); 144 wait_state.handles[index]);
131 } else { 145 return true;
132 switch (result) {
133 case MOJO_RESULT_INVALID_ARGUMENT:
134 case MOJO_RESULT_FAILED_PRECONDITION:
135 RemoveFirstInvalidHandle(wait_state);
136 break;
137 case MOJO_RESULT_DEADLINE_EXCEEDED:
138 break;
139 default:
140 assert(false);
141 }
142 } 146 }
143 147
144 NotifyDeadlineExceeded(); 148 switch (result) {
149 case MOJO_RESULT_INVALID_ARGUMENT:
150 case MOJO_RESULT_FAILED_PRECONDITION:
151 return RemoveFirstInvalidHandle(wait_state);
152 case MOJO_RESULT_DEADLINE_EXCEEDED:
153 return NotifyDeadlineExceeded();
154 }
155
156 assert(false);
157 return false;
145 } 158 }
146 159
147 void RunLoop::NotifyDeadlineExceeded() { 160 bool RunLoop::NotifyDeadlineExceeded() {
161 bool notified = false;
162
148 // Make a copy in case someone tries to add/remove new handlers as part of 163 // Make a copy in case someone tries to add/remove new handlers as part of
149 // notifying. 164 // notifying.
150 const HandleToHandlerData cloned_handlers(handler_data_); 165 const HandleToHandlerData cloned_handlers(handler_data_);
151 const MojoTimeTicks now(GetTimeTicksNow()); 166 const MojoTimeTicks now(GetTimeTicksNow());
152 for (HandleToHandlerData::const_iterator i = cloned_handlers.begin(); 167 for (HandleToHandlerData::const_iterator i = cloned_handlers.begin();
153 i != cloned_handlers.end(); ++i) { 168 i != cloned_handlers.end(); ++i) {
154 // Since we're iterating over a clone of the handlers, verify the handler is 169 // Since we're iterating over a clone of the handlers, verify the handler is
155 // still valid before notifying. 170 // still valid before notifying.
156 if (i->second.deadline != kInvalidTimeTicks && 171 if (i->second.deadline != kInvalidTimeTicks &&
157 i->second.deadline < now && 172 i->second.deadline < now &&
158 handler_data_.find(i->first) != handler_data_.end() && 173 handler_data_.find(i->first) != handler_data_.end() &&
159 handler_data_[i->first].id == i->second.id) { 174 handler_data_[i->first].id == i->second.id) {
160 handler_data_.erase(i->first); 175 handler_data_.erase(i->first);
161 i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED); 176 i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED);
177 notified = true;
162 } 178 }
163 } 179 }
180
181 return notified;
164 } 182 }
165 183
166 void RunLoop::RemoveFirstInvalidHandle(const WaitState& wait_state) { 184 bool RunLoop::RemoveFirstInvalidHandle(const WaitState& wait_state) {
167 for (size_t i = 0; i < wait_state.handles.size(); ++i) { 185 for (size_t i = 0; i < wait_state.handles.size(); ++i) {
168 const MojoResult result = 186 const MojoResult result =
169 mojo::Wait(wait_state.handles[i], wait_state.wait_flags[i], 187 mojo::Wait(wait_state.handles[i], wait_state.wait_flags[i],
170 static_cast<MojoDeadline>(0)); 188 static_cast<MojoDeadline>(0));
171 if (result == MOJO_RESULT_INVALID_ARGUMENT || 189 if (result == MOJO_RESULT_INVALID_ARGUMENT ||
172 result == MOJO_RESULT_FAILED_PRECONDITION) { 190 result == MOJO_RESULT_FAILED_PRECONDITION) {
173 // Remove the handle first, this way if OnHandleError() tries to remove 191 // Remove the handle first, this way if OnHandleError() tries to remove
174 // the handle our iterator isn't invalidated. 192 // the handle our iterator isn't invalidated.
175 assert(handler_data_.find(wait_state.handles[i]) != handler_data_.end()); 193 assert(handler_data_.find(wait_state.handles[i]) != handler_data_.end());
176 RunLoopHandler* handler = 194 RunLoopHandler* handler =
177 handler_data_[wait_state.handles[i]].handler; 195 handler_data_[wait_state.handles[i]].handler;
178 handler_data_.erase(wait_state.handles[i]); 196 handler_data_.erase(wait_state.handles[i]);
179 handler->OnHandleError(wait_state.handles[i], result); 197 handler->OnHandleError(wait_state.handles[i], result);
180 return; 198 return true;
181 } else {
182 assert(MOJO_RESULT_DEADLINE_EXCEEDED == result);
183 } 199 }
200 assert(MOJO_RESULT_DEADLINE_EXCEEDED == result);
184 } 201 }
202 return false;
185 } 203 }
186 204
187 RunLoop::WaitState RunLoop::GetWaitState() const { 205 RunLoop::WaitState RunLoop::GetWaitState(bool non_blocking) const {
188 WaitState wait_state; 206 WaitState wait_state;
189 MojoTimeTicks min_time = kInvalidTimeTicks; 207 MojoTimeTicks min_time = kInvalidTimeTicks;
190 for (HandleToHandlerData::const_iterator i = handler_data_.begin(); 208 for (HandleToHandlerData::const_iterator i = handler_data_.begin();
191 i != handler_data_.end(); ++i) { 209 i != handler_data_.end(); ++i) {
192 wait_state.handles.push_back(i->first); 210 wait_state.handles.push_back(i->first);
193 wait_state.wait_flags.push_back(i->second.wait_flags); 211 wait_state.wait_flags.push_back(i->second.wait_flags);
194 if (i->second.deadline != kInvalidTimeTicks && 212 if (!non_blocking && i->second.deadline != kInvalidTimeTicks &&
195 (min_time == kInvalidTimeTicks || i->second.deadline < min_time)) { 213 (min_time == kInvalidTimeTicks || i->second.deadline < min_time)) {
196 min_time = i->second.deadline; 214 min_time = i->second.deadline;
197 } 215 }
198 } 216 }
199 if (min_time != kInvalidTimeTicks) { 217 if (non_blocking) {
218 wait_state.deadline = static_cast<MojoDeadline>(0);
219 } else if (min_time != kInvalidTimeTicks) {
200 const MojoTimeTicks now = GetTimeTicksNow(); 220 const MojoTimeTicks now = GetTimeTicksNow();
201 if (min_time < now) 221 if (min_time < now)
202 wait_state.deadline = static_cast<MojoDeadline>(0); 222 wait_state.deadline = static_cast<MojoDeadline>(0);
203 else 223 else
204 wait_state.deadline = static_cast<MojoDeadline>(min_time - now); 224 wait_state.deadline = static_cast<MojoDeadline>(min_time - now);
205 } 225 }
206 return wait_state; 226 return wait_state;
207 } 227 }
208 228
209 } // namespace mojo 229 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698