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(); |
| 303 } else { |
| 304 pump_ = |
| 305 CreateMessagePumpForType(lazy_init_options_->message_loop_type).Pass(); |
| 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 23 matching lines...) Expand all Loading... |
296 | 349 |
297 void MessageLoop::PostNonNestableDelayedTask( | 350 void MessageLoop::PostNonNestableDelayedTask( |
298 const tracked_objects::Location& from_here, | 351 const tracked_objects::Location& from_here, |
299 const Closure& task, | 352 const Closure& task, |
300 TimeDelta delay) { | 353 TimeDelta delay) { |
301 DCHECK(!task.is_null()) << from_here.ToString(); | 354 DCHECK(!task.is_null()) << from_here.ToString(); |
302 incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, false); | 355 incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, false); |
303 } | 356 } |
304 | 357 |
305 void MessageLoop::Run() { | 358 void MessageLoop::Run() { |
| 359 DCHECK(!lazy_init_options_); |
306 RunLoop run_loop; | 360 RunLoop run_loop; |
307 run_loop.Run(); | 361 run_loop.Run(); |
308 } | 362 } |
309 | 363 |
310 void MessageLoop::RunUntilIdle() { | 364 void MessageLoop::RunUntilIdle() { |
| 365 DCHECK(!lazy_init_options_); |
311 RunLoop run_loop; | 366 RunLoop run_loop; |
312 run_loop.RunUntilIdle(); | 367 run_loop.RunUntilIdle(); |
313 } | 368 } |
314 | 369 |
315 void MessageLoop::QuitWhenIdle() { | 370 void MessageLoop::QuitWhenIdle() { |
316 DCHECK_EQ(this, current()); | 371 DCHECK_EQ(this, current()); |
317 if (run_loop_) { | 372 if (run_loop_) { |
318 run_loop_->quit_when_idle_received_ = true; | 373 run_loop_->quit_when_idle_received_ = true; |
319 } else { | 374 } else { |
320 NOTREACHED() << "Must be inside Run to call Quit"; | 375 NOTREACHED() << "Must be inside Run to call Quit"; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 } | 435 } |
381 | 436 |
382 bool MessageLoop::IsIdleForTesting() { | 437 bool MessageLoop::IsIdleForTesting() { |
383 // We only check the imcoming queue|, since we don't want to lock the work | 438 // We only check the imcoming queue|, since we don't want to lock the work |
384 // queue. | 439 // queue. |
385 return incoming_task_queue_->IsIdleForTesting(); | 440 return incoming_task_queue_->IsIdleForTesting(); |
386 } | 441 } |
387 | 442 |
388 //------------------------------------------------------------------------------ | 443 //------------------------------------------------------------------------------ |
389 | 444 |
| 445 MessageLoop::MessageLoop(scoped_ptr<LazyInitOptions> options) |
| 446 : type_(GetMessageLoopType(options.get())), |
| 447 #if defined(OS_WIN) |
| 448 pending_high_res_tasks_(0), |
| 449 in_high_res_mode_(false), |
| 450 #endif |
| 451 nestable_tasks_allowed_(true), |
| 452 #if defined(OS_WIN) |
| 453 os_modal_loop_(false), |
| 454 #endif // OS_WIN |
| 455 lazy_init_options_(options.Pass()), |
| 456 message_histogram_(NULL), |
| 457 run_loop_(NULL) { |
| 458 incoming_task_queue_ = |
| 459 internal::IncomingTaskQueue::CreateForLazyInitMessageLoop(this); |
| 460 message_loop_proxy_ = |
| 461 internal::MessageLoopProxyImpl::CreateForLazyInit(incoming_task_queue_); |
| 462 } |
| 463 |
390 void MessageLoop::Init() { | 464 void MessageLoop::Init() { |
| 465 DCHECK(!lazy_init_options_) << "should not be called when created for " |
| 466 "lazy initialization"; |
391 DCHECK(!current()) << "should only have one message loop per thread"; | 467 DCHECK(!current()) << "should only have one message loop per thread"; |
392 lazy_tls_ptr.Pointer()->Set(this); | 468 lazy_tls_ptr.Pointer()->Set(this); |
393 | 469 |
394 incoming_task_queue_ = new internal::IncomingTaskQueue(this); | 470 incoming_task_queue_ = new internal::IncomingTaskQueue(this); |
395 message_loop_proxy_ = | 471 message_loop_proxy_ = |
396 new internal::MessageLoopProxyImpl(incoming_task_queue_); | 472 internal::MessageLoopProxyImpl::Create(incoming_task_queue_); |
397 thread_task_runner_handle_.reset( | 473 thread_task_runner_handle_.reset( |
398 new ThreadTaskRunnerHandle(message_loop_proxy_)); | 474 new ThreadTaskRunnerHandle(message_loop_proxy_)); |
399 } | 475 } |
400 | 476 |
401 void MessageLoop::RunHandler() { | 477 void MessageLoop::RunHandler() { |
402 DCHECK_EQ(this, current()); | 478 DCHECK_EQ(this, current()); |
403 | 479 |
404 StartHistogrammer(); | 480 StartHistogrammer(); |
405 | 481 |
406 #if defined(OS_WIN) | 482 #if defined(OS_WIN) |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 persistent, | 791 persistent, |
716 mode, | 792 mode, |
717 controller, | 793 controller, |
718 delegate); | 794 delegate); |
719 } | 795 } |
720 #endif | 796 #endif |
721 | 797 |
722 #endif // !defined(OS_NACL_SFI) | 798 #endif // !defined(OS_NACL_SFI) |
723 | 799 |
724 } // namespace base | 800 } // namespace base |
OLD | NEW |