Chromium Code Reviews| 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 |