OLD | NEW |
---|---|
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 "base/message_loop/message_loop.h" | 5 #include "base/message_loop/message_loop.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 #elif defined(OS_POSIX) | 93 #elif defined(OS_POSIX) |
94 typedef MessagePumpLibevent MessagePumpForIO; | 94 typedef MessagePumpLibevent MessagePumpForIO; |
95 #endif | 95 #endif |
96 | 96 |
97 #if !defined(OS_NACL_SFI) | 97 #if !defined(OS_NACL_SFI) |
98 MessagePumpForIO* ToPumpIO(MessagePump* pump) { | 98 MessagePumpForIO* ToPumpIO(MessagePump* pump) { |
99 return static_cast<MessagePumpForIO*>(pump); | 99 return static_cast<MessagePumpForIO*>(pump); |
100 } | 100 } |
101 #endif // !defined(OS_NACL_SFI) | 101 #endif // !defined(OS_NACL_SFI) |
102 | 102 |
103 MessageLoop::Type GetMessageLoopType(MessageLoop::LazyInitOptions* options) { | |
104 if (options->message_pump_factory.is_null()) | |
105 return options->message_loop_type; | |
106 return MessageLoop::TYPE_CUSTOM; | |
107 } | |
108 | |
103 } // namespace | 109 } // namespace |
104 | 110 |
105 //------------------------------------------------------------------------------ | 111 //------------------------------------------------------------------------------ |
106 | 112 |
113 MessageLoop::LazyInitOptions::LazyInitOptions() | |
114 : message_loop_type(MessageLoop::TYPE_DEFAULT), | |
115 timer_slack(TIMER_SLACK_NONE) { | |
116 } | |
117 | |
118 MessageLoop::LazyInitOptions::~LazyInitOptions() { | |
119 } | |
120 | |
121 //------------------------------------------------------------------------------ | |
122 | |
107 MessageLoop::TaskObserver::TaskObserver() { | 123 MessageLoop::TaskObserver::TaskObserver() { |
108 } | 124 } |
109 | 125 |
110 MessageLoop::TaskObserver::~TaskObserver() { | 126 MessageLoop::TaskObserver::~TaskObserver() { |
111 } | 127 } |
112 | 128 |
113 MessageLoop::DestructionObserver::~DestructionObserver() { | 129 MessageLoop::DestructionObserver::~DestructionObserver() { |
114 } | 130 } |
115 | 131 |
116 //------------------------------------------------------------------------------ | 132 //------------------------------------------------------------------------------ |
(...skipping 26 matching lines...) Expand all Loading... | |
143 #if defined(OS_WIN) | 159 #if defined(OS_WIN) |
144 os_modal_loop_(false), | 160 os_modal_loop_(false), |
145 #endif // OS_WIN | 161 #endif // OS_WIN |
146 message_histogram_(NULL), | 162 message_histogram_(NULL), |
147 run_loop_(NULL) { | 163 run_loop_(NULL) { |
148 DCHECK(pump_.get()); | 164 DCHECK(pump_.get()); |
149 Init(); | 165 Init(); |
150 } | 166 } |
151 | 167 |
152 MessageLoop::~MessageLoop() { | 168 MessageLoop::~MessageLoop() { |
169 if (lazy_init_options_) { | |
170 // This message loop is destructed before we call LazyInit. | |
171 DCHECK(current() == NULL); | |
172 DCHECK(incoming_task_queue_->empty()); | |
173 DCHECK(!pump_); | |
174 DCHECK(!destruction_observers_.might_have_observers()); | |
175 incoming_task_queue_->WillDestroyCurrentMessageLoop(); | |
176 return; | |
177 } | |
178 | |
153 DCHECK_EQ(this, current()); | 179 DCHECK_EQ(this, current()); |
154 | 180 |
155 // iOS just attaches to the loop, it doesn't Run it. | 181 // iOS just attaches to the loop, it doesn't Run it. |
156 // TODO(stuartmorgan): Consider wiring up a Detach(). | 182 // TODO(stuartmorgan): Consider wiring up a Detach(). |
157 #if !defined(OS_IOS) | 183 #if !defined(OS_IOS) |
158 DCHECK(!run_loop_); | 184 DCHECK(!run_loop_); |
159 #endif | 185 #endif |
160 | 186 |
161 #if defined(OS_WIN) | 187 #if defined(OS_WIN) |
162 if (in_high_res_mode_) | 188 if (in_high_res_mode_) |
(...skipping 25 matching lines...) Expand all Loading... | |
188 // Tell the incoming queue that we are dying. | 214 // Tell the incoming queue that we are dying. |
189 incoming_task_queue_->WillDestroyCurrentMessageLoop(); | 215 incoming_task_queue_->WillDestroyCurrentMessageLoop(); |
190 incoming_task_queue_ = NULL; | 216 incoming_task_queue_ = NULL; |
191 message_loop_proxy_ = NULL; | 217 message_loop_proxy_ = NULL; |
192 | 218 |
193 // OK, now make it so that no one can find us. | 219 // OK, now make it so that no one can find us. |
194 lazy_tls_ptr.Pointer()->Set(NULL); | 220 lazy_tls_ptr.Pointer()->Set(NULL); |
195 } | 221 } |
196 | 222 |
197 // static | 223 // static |
224 MessageLoop* MessageLoop::CreateForLazyInit( | |
225 scoped_ptr<LazyInitOptions> options) { | |
226 return new MessageLoop(options.Pass()); | |
227 } | |
228 | |
229 // static | |
198 MessageLoop* MessageLoop::current() { | 230 MessageLoop* MessageLoop::current() { |
199 // TODO(darin): sadly, we cannot enable this yet since people call us even | 231 // TODO(darin): sadly, we cannot enable this yet since people call us even |
200 // when they have no intention of using us. | 232 // when they have no intention of using us. |
201 // DCHECK(loop) << "Ouch, did you forget to initialize me?"; | 233 // DCHECK(loop) << "Ouch, did you forget to initialize me?"; |
202 return lazy_tls_ptr.Pointer()->Get(); | 234 return lazy_tls_ptr.Pointer()->Get(); |
203 } | 235 } |
204 | 236 |
205 // static | 237 // static |
206 void MessageLoop::EnableHistogrammer(bool enable) { | 238 void MessageLoop::EnableHistogrammer(bool enable) { |
207 enable_histogrammer_ = enable; | 239 enable_histogrammer_ = enable; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 | 285 |
254 #if defined(OS_ANDROID) | 286 #if defined(OS_ANDROID) |
255 if (type == MessageLoop::TYPE_JAVA) | 287 if (type == MessageLoop::TYPE_JAVA) |
256 return scoped_ptr<MessagePump>(new MessagePumpForUI()); | 288 return scoped_ptr<MessagePump>(new MessagePumpForUI()); |
257 #endif | 289 #endif |
258 | 290 |
259 DCHECK_EQ(MessageLoop::TYPE_DEFAULT, type); | 291 DCHECK_EQ(MessageLoop::TYPE_DEFAULT, type); |
260 return MESSAGE_PUMP_DEFAULT; | 292 return MESSAGE_PUMP_DEFAULT; |
261 } | 293 } |
262 | 294 |
295 void MessageLoop::LazyInit() { | |
296 DCHECK(lazy_init_options_) | |
297 << "should be called only when created for lazy init"; | |
298 DCHECK(!current()) << "should only have one message loop per thread"; | |
299 lazy_tls_ptr.Pointer()->Set(this); | |
300 | |
301 if (!lazy_init_options_->message_pump_factory.is_null()) { | |
302 pump_ = lazy_init_options_->message_pump_factory.Run().Pass(); | |
rvargas (doing something else)
2015/03/26 02:19:26
no need to Pass()
kinuko
2015/04/13 02:02:59
Done.
| |
303 } else { | |
304 pump_ = | |
305 CreateMessagePumpForType(lazy_init_options_->message_loop_type).Pass(); | |
rvargas (doing something else)
2015/03/26 02:19:27
no need to Pass()
kinuko
2015/04/13 02:02:59
Done.
| |
306 } | |
307 SetTimerSlack(lazy_init_options_->timer_slack); | |
308 lazy_init_options_.reset(); | |
309 | |
310 incoming_task_queue_->DidInitializeMessageLoop(); | |
311 message_loop_proxy_->LazyInit(); | |
312 thread_task_runner_handle_.reset( | |
313 new ThreadTaskRunnerHandle(message_loop_proxy_)); | |
314 } | |
315 | |
263 void MessageLoop::AddDestructionObserver( | 316 void MessageLoop::AddDestructionObserver( |
264 DestructionObserver* destruction_observer) { | 317 DestructionObserver* destruction_observer) { |
265 DCHECK_EQ(this, current()); | 318 DCHECK_EQ(this, current()); |
266 destruction_observers_.AddObserver(destruction_observer); | 319 destruction_observers_.AddObserver(destruction_observer); |
267 } | 320 } |
268 | 321 |
269 void MessageLoop::RemoveDestructionObserver( | 322 void MessageLoop::RemoveDestructionObserver( |
270 DestructionObserver* destruction_observer) { | 323 DestructionObserver* destruction_observer) { |
271 DCHECK_EQ(this, current()); | 324 DCHECK_EQ(this, current()); |
272 destruction_observers_.RemoveObserver(destruction_observer); | 325 destruction_observers_.RemoveObserver(destruction_observer); |
(...skipping 19 matching lines...) Expand all Loading... | |
292 } | 345 } |
293 | 346 |
294 void MessageLoop::PostNonNestableDelayedTask( | 347 void MessageLoop::PostNonNestableDelayedTask( |
295 const tracked_objects::Location& from_here, | 348 const tracked_objects::Location& from_here, |
296 const Closure& task, | 349 const Closure& task, |
297 TimeDelta delay) { | 350 TimeDelta delay) { |
298 message_loop_proxy_->PostNonNestableDelayedTask(from_here, task, delay); | 351 message_loop_proxy_->PostNonNestableDelayedTask(from_here, task, delay); |
299 } | 352 } |
300 | 353 |
301 void MessageLoop::Run() { | 354 void MessageLoop::Run() { |
355 DCHECK(!lazy_init_options_); | |
302 RunLoop run_loop; | 356 RunLoop run_loop; |
303 run_loop.Run(); | 357 run_loop.Run(); |
304 } | 358 } |
305 | 359 |
306 void MessageLoop::RunUntilIdle() { | 360 void MessageLoop::RunUntilIdle() { |
361 DCHECK(!lazy_init_options_); | |
307 RunLoop run_loop; | 362 RunLoop run_loop; |
308 run_loop.RunUntilIdle(); | 363 run_loop.RunUntilIdle(); |
309 } | 364 } |
310 | 365 |
311 void MessageLoop::QuitWhenIdle() { | 366 void MessageLoop::QuitWhenIdle() { |
312 DCHECK_EQ(this, current()); | 367 DCHECK_EQ(this, current()); |
313 if (run_loop_) { | 368 if (run_loop_) { |
314 run_loop_->quit_when_idle_received_ = true; | 369 run_loop_->quit_when_idle_received_ = true; |
315 } else { | 370 } else { |
316 NOTREACHED() << "Must be inside Run to call Quit"; | 371 NOTREACHED() << "Must be inside Run to call Quit"; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 } | 431 } |
377 | 432 |
378 bool MessageLoop::IsIdleForTesting() { | 433 bool MessageLoop::IsIdleForTesting() { |
379 // We only check the imcoming queue|, since we don't want to lock the work | 434 // We only check the imcoming queue|, since we don't want to lock the work |
380 // queue. | 435 // queue. |
381 return incoming_task_queue_->IsIdleForTesting(); | 436 return incoming_task_queue_->IsIdleForTesting(); |
382 } | 437 } |
383 | 438 |
384 //------------------------------------------------------------------------------ | 439 //------------------------------------------------------------------------------ |
385 | 440 |
441 MessageLoop::MessageLoop(scoped_ptr<LazyInitOptions> options) | |
442 : type_(GetMessageLoopType(options.get())), | |
443 #if defined(OS_WIN) | |
444 pending_high_res_tasks_(0), | |
445 in_high_res_mode_(false), | |
446 #endif | |
447 nestable_tasks_allowed_(true), | |
448 #if defined(OS_WIN) | |
449 os_modal_loop_(false), | |
450 #endif // OS_WIN | |
451 lazy_init_options_(options.Pass()), | |
452 message_histogram_(NULL), | |
453 run_loop_(NULL) { | |
454 incoming_task_queue_ = | |
455 internal::IncomingTaskQueue::CreateForLazyInitMessageLoop(this); | |
456 message_loop_proxy_ = | |
457 internal::MessageLoopProxyImpl::CreateForLazyInit(incoming_task_queue_); | |
458 } | |
459 | |
386 void MessageLoop::Init() { | 460 void MessageLoop::Init() { |
461 DCHECK(!lazy_init_options_) << "should not be called when created for " | |
462 "lazy initialization"; | |
387 DCHECK(!current()) << "should only have one message loop per thread"; | 463 DCHECK(!current()) << "should only have one message loop per thread"; |
388 lazy_tls_ptr.Pointer()->Set(this); | 464 lazy_tls_ptr.Pointer()->Set(this); |
389 | 465 |
390 incoming_task_queue_ = new internal::IncomingTaskQueue(this); | 466 incoming_task_queue_ = new internal::IncomingTaskQueue(this); |
391 message_loop_proxy_ = | 467 message_loop_proxy_ = |
392 new internal::MessageLoopProxyImpl(incoming_task_queue_); | 468 internal::MessageLoopProxyImpl::Create(incoming_task_queue_); |
393 thread_task_runner_handle_.reset( | 469 thread_task_runner_handle_.reset( |
394 new ThreadTaskRunnerHandle(message_loop_proxy_)); | 470 new ThreadTaskRunnerHandle(message_loop_proxy_)); |
395 } | 471 } |
396 | 472 |
397 void MessageLoop::RunHandler() { | 473 void MessageLoop::RunHandler() { |
398 DCHECK_EQ(this, current()); | 474 DCHECK_EQ(this, current()); |
399 | 475 |
400 StartHistogrammer(); | 476 StartHistogrammer(); |
401 | 477 |
402 #if defined(OS_WIN) | 478 #if defined(OS_WIN) |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
711 persistent, | 787 persistent, |
712 mode, | 788 mode, |
713 controller, | 789 controller, |
714 delegate); | 790 delegate); |
715 } | 791 } |
716 #endif | 792 #endif |
717 | 793 |
718 #endif // !defined(OS_NACL_SFI) | 794 #endif // !defined(OS_NACL_SFI) |
719 | 795 |
720 } // namespace base | 796 } // namespace base |
OLD | NEW |