| 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 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 | 68 |
| 69 MessageLoop::TaskObserver::TaskObserver() { | 69 MessageLoop::TaskObserver::TaskObserver() { |
| 70 } | 70 } |
| 71 | 71 |
| 72 MessageLoop::TaskObserver::~TaskObserver() { | 72 MessageLoop::TaskObserver::~TaskObserver() { |
| 73 } | 73 } |
| 74 | 74 |
| 75 MessageLoop::DestructionObserver::~DestructionObserver() { | 75 MessageLoop::DestructionObserver::~DestructionObserver() { |
| 76 } | 76 } |
| 77 | 77 |
| 78 MessageLoop::NestingObserver::~NestingObserver() {} | |
| 79 | |
| 80 //------------------------------------------------------------------------------ | 78 //------------------------------------------------------------------------------ |
| 81 | 79 |
| 82 MessageLoop::MessageLoop(Type type) | 80 MessageLoop::MessageLoop(Type type) |
| 83 : MessageLoop(type, MessagePumpFactoryCallback()) { | 81 : MessageLoop(type, MessagePumpFactoryCallback()) { |
| 84 BindToCurrentThread(); | 82 BindToCurrentThread(); |
| 85 } | 83 } |
| 86 | 84 |
| 87 MessageLoop::MessageLoop(std::unique_ptr<MessagePump> pump) | 85 MessageLoop::MessageLoop(std::unique_ptr<MessagePump> pump) |
| 88 : MessageLoop(TYPE_CUSTOM, BindOnce(&ReturnPump, Passed(&pump))) { | 86 : MessageLoop(TYPE_CUSTOM, BindOnce(&ReturnPump, Passed(&pump))) { |
| 89 BindToCurrentThread(); | 87 BindToCurrentThread(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 129 |
| 132 // Tell the incoming queue that we are dying. | 130 // Tell the incoming queue that we are dying. |
| 133 incoming_task_queue_->WillDestroyCurrentMessageLoop(); | 131 incoming_task_queue_->WillDestroyCurrentMessageLoop(); |
| 134 incoming_task_queue_ = NULL; | 132 incoming_task_queue_ = NULL; |
| 135 unbound_task_runner_ = NULL; | 133 unbound_task_runner_ = NULL; |
| 136 task_runner_ = NULL; | 134 task_runner_ = NULL; |
| 137 | 135 |
| 138 // OK, now make it so that no one can find us. | 136 // OK, now make it so that no one can find us. |
| 139 if (current() == this) | 137 if (current() == this) |
| 140 GetTLSMessageLoop()->Set(nullptr); | 138 GetTLSMessageLoop()->Set(nullptr); |
| 139 |
| 140 RunLoop::ResetTLSState(); |
| 141 } | 141 } |
| 142 | 142 |
| 143 // static | 143 // static |
| 144 MessageLoop* MessageLoop::current() { | 144 MessageLoop* MessageLoop::current() { |
| 145 // TODO(darin): sadly, we cannot enable this yet since people call us even | 145 // TODO(darin): sadly, we cannot enable this yet since people call us even |
| 146 // when they have no intention of using us. | 146 // when they have no intention of using us. |
| 147 // DCHECK(loop) << "Ouch, did you forget to initialize me?"; | 147 // DCHECK(loop) << "Ouch, did you forget to initialize me?"; |
| 148 return GetTLSMessageLoop()->Get(); | 148 return GetTLSMessageLoop()->Get(); |
| 149 } | 149 } |
| 150 | 150 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 DCHECK_EQ(this, current()); | 207 DCHECK_EQ(this, current()); |
| 208 destruction_observers_.AddObserver(destruction_observer); | 208 destruction_observers_.AddObserver(destruction_observer); |
| 209 } | 209 } |
| 210 | 210 |
| 211 void MessageLoop::RemoveDestructionObserver( | 211 void MessageLoop::RemoveDestructionObserver( |
| 212 DestructionObserver* destruction_observer) { | 212 DestructionObserver* destruction_observer) { |
| 213 DCHECK_EQ(this, current()); | 213 DCHECK_EQ(this, current()); |
| 214 destruction_observers_.RemoveObserver(destruction_observer); | 214 destruction_observers_.RemoveObserver(destruction_observer); |
| 215 } | 215 } |
| 216 | 216 |
| 217 void MessageLoop::AddNestingObserver(NestingObserver* observer) { | |
| 218 DCHECK_EQ(this, current()); | |
| 219 CHECK(allow_nesting_); | |
| 220 nesting_observers_.AddObserver(observer); | |
| 221 } | |
| 222 | |
| 223 void MessageLoop::RemoveNestingObserver(NestingObserver* observer) { | |
| 224 DCHECK_EQ(this, current()); | |
| 225 CHECK(allow_nesting_); | |
| 226 nesting_observers_.RemoveObserver(observer); | |
| 227 } | |
| 228 | |
| 229 void MessageLoop::QuitWhenIdle() { | 217 void MessageLoop::QuitWhenIdle() { |
| 230 DCHECK_EQ(this, current()); | 218 DCHECK_EQ(this, current()); |
| 231 if (run_loop_) { | 219 if (run_loop_) { |
| 232 run_loop_->QuitWhenIdle(); | 220 run_loop_->QuitWhenIdle(); |
| 233 } else { | 221 } else { |
| 234 NOTREACHED() << "Must be inside Run to call QuitWhenIdle"; | 222 NOTREACHED() << "Must be inside Run to call QuitWhenIdle"; |
| 235 } | 223 } |
| 236 } | 224 } |
| 237 | 225 |
| 238 void MessageLoop::QuitNow() { | 226 void MessageLoop::QuitNow() { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 252 MessageLoop::current()->QuitWhenIdle(); | 240 MessageLoop::current()->QuitWhenIdle(); |
| 253 } | 241 } |
| 254 | 242 |
| 255 // static | 243 // static |
| 256 Closure MessageLoop::QuitWhenIdleClosure() { | 244 Closure MessageLoop::QuitWhenIdleClosure() { |
| 257 return Bind(&QuitCurrentWhenIdle); | 245 return Bind(&QuitCurrentWhenIdle); |
| 258 } | 246 } |
| 259 | 247 |
| 260 void MessageLoop::SetNestableTasksAllowed(bool allowed) { | 248 void MessageLoop::SetNestableTasksAllowed(bool allowed) { |
| 261 if (allowed) { | 249 if (allowed) { |
| 262 CHECK(allow_nesting_); | 250 CHECK(base::RunLoop::IsNestingAllowedOnCurrentThread()); |
| 263 | 251 |
| 264 // Kick the native pump just in case we enter a OS-driven nested message | 252 // Kick the native pump just in case we enter a OS-driven nested message |
| 265 // loop. | 253 // loop. |
| 266 pump_->ScheduleWork(); | 254 pump_->ScheduleWork(); |
| 267 } | 255 } |
| 268 nestable_tasks_allowed_ = allowed; | 256 nestable_tasks_allowed_ = allowed; |
| 269 } | 257 } |
| 270 | 258 |
| 271 bool MessageLoop::NestableTasksAllowed() const { | 259 bool MessageLoop::NestableTasksAllowed() const { |
| 272 return nestable_tasks_allowed_; | 260 return nestable_tasks_allowed_; |
| 273 } | 261 } |
| 274 | 262 |
| 275 bool MessageLoop::IsNested() { | 263 // TODO(gab): Migrate TaskObservers to RunLoop as part of separating concerns |
| 276 return run_loop_->run_depth_ > 1; | 264 // between MessageLoop and RunLoop and making MessageLoop a swappable |
| 277 } | 265 // implementation detail. http://crbug.com/703346 |
| 278 | |
| 279 void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { | 266 void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { |
| 280 DCHECK_EQ(this, current()); | 267 DCHECK_EQ(this, current()); |
| 281 CHECK(allow_task_observers_); | 268 CHECK(allow_task_observers_); |
| 282 task_observers_.AddObserver(task_observer); | 269 task_observers_.AddObserver(task_observer); |
| 283 } | 270 } |
| 284 | 271 |
| 285 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { | 272 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { |
| 286 DCHECK_EQ(this, current()); | 273 DCHECK_EQ(this, current()); |
| 287 CHECK(allow_task_observers_); | 274 CHECK(allow_task_observers_); |
| 288 task_observers_.RemoveObserver(task_observer); | 275 task_observers_.RemoveObserver(task_observer); |
| 289 } | 276 } |
| 290 | 277 |
| 291 bool MessageLoop::is_running() const { | |
| 292 DCHECK_EQ(this, current()); | |
| 293 return run_loop_ != NULL; | |
| 294 } | |
| 295 | |
| 296 bool MessageLoop::HasHighResolutionTasks() { | 278 bool MessageLoop::HasHighResolutionTasks() { |
| 297 return incoming_task_queue_->HasHighResolutionTasks(); | 279 return incoming_task_queue_->HasHighResolutionTasks(); |
| 298 } | 280 } |
| 299 | 281 |
| 300 bool MessageLoop::IsIdleForTesting() { | 282 bool MessageLoop::IsIdleForTesting() { |
| 301 // We only check the incoming queue, since we don't want to lock the work | 283 // We only check the incoming queue, since we don't want to lock the work |
| 302 // queue. | 284 // queue. |
| 303 return incoming_task_queue_->IsIdleForTesting(); | 285 return incoming_task_queue_->IsIdleForTesting(); |
| 304 } | 286 } |
| 305 | 287 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 DCHECK_EQ(this, current()); | 358 DCHECK_EQ(this, current()); |
| 377 // Clear the previous thread task runner first, because only one can exist at | 359 // Clear the previous thread task runner first, because only one can exist at |
| 378 // a time. | 360 // a time. |
| 379 thread_task_runner_handle_.reset(); | 361 thread_task_runner_handle_.reset(); |
| 380 thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_)); | 362 thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_)); |
| 381 } | 363 } |
| 382 | 364 |
| 383 void MessageLoop::RunHandler() { | 365 void MessageLoop::RunHandler() { |
| 384 DCHECK_EQ(this, current()); | 366 DCHECK_EQ(this, current()); |
| 385 DCHECK(run_loop_); | 367 DCHECK(run_loop_); |
| 386 CHECK(allow_nesting_ || run_loop_->run_depth_ == 1); | |
| 387 pump_->Run(this); | 368 pump_->Run(this); |
| 388 } | 369 } |
| 389 | 370 |
| 390 bool MessageLoop::ProcessNextDelayedNonNestableTask() { | 371 bool MessageLoop::ProcessNextDelayedNonNestableTask() { |
| 391 if (run_loop_->run_depth_ != 1) | 372 if (is_nested_) |
| 392 return false; | 373 return false; |
| 393 | 374 |
| 394 if (deferred_non_nestable_work_queue_.empty()) | 375 if (deferred_non_nestable_work_queue_.empty()) |
| 395 return false; | 376 return false; |
| 396 | 377 |
| 397 PendingTask pending_task = | 378 PendingTask pending_task = |
| 398 std::move(deferred_non_nestable_work_queue_.front()); | 379 std::move(deferred_non_nestable_work_queue_.front()); |
| 399 deferred_non_nestable_work_queue_.pop(); | 380 deferred_non_nestable_work_queue_.pop(); |
| 400 | 381 |
| 401 RunTask(&pending_task); | 382 RunTask(&pending_task); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 423 task_annotator_.RunTask("MessageLoop::PostTask", pending_task); | 404 task_annotator_.RunTask("MessageLoop::PostTask", pending_task); |
| 424 for (auto& observer : task_observers_) | 405 for (auto& observer : task_observers_) |
| 425 observer.DidProcessTask(*pending_task); | 406 observer.DidProcessTask(*pending_task); |
| 426 | 407 |
| 427 nestable_tasks_allowed_ = true; | 408 nestable_tasks_allowed_ = true; |
| 428 | 409 |
| 429 current_pending_task_ = nullptr; | 410 current_pending_task_ = nullptr; |
| 430 } | 411 } |
| 431 | 412 |
| 432 bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) { | 413 bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) { |
| 433 if (pending_task.nestable || run_loop_->run_depth_ == 1) { | 414 if (pending_task.nestable || !is_nested_) { |
| 434 RunTask(&pending_task); | 415 RunTask(&pending_task); |
| 435 // Show that we ran a task (Note: a new one might arrive as a | 416 // Show that we ran a task (Note: a new one might arrive as a |
| 436 // consequence!). | 417 // consequence!). |
| 437 return true; | 418 return true; |
| 438 } | 419 } |
| 439 | 420 |
| 440 // We couldn't run the task now because we're in a nested message loop | 421 // We couldn't run the task now because we're in a nested message loop |
| 441 // and the task isn't nestable. | 422 // and the task isn't nestable. |
| 442 deferred_non_nestable_work_queue_.push(std::move(pending_task)); | 423 deferred_non_nestable_work_queue_.push(std::move(pending_task)); |
| 443 return false; | 424 return false; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 #else | 470 #else |
| 490 incoming_task_queue_->ReloadWorkQueue(&work_queue_); | 471 incoming_task_queue_->ReloadWorkQueue(&work_queue_); |
| 491 #endif | 472 #endif |
| 492 } | 473 } |
| 493 } | 474 } |
| 494 | 475 |
| 495 void MessageLoop::ScheduleWork() { | 476 void MessageLoop::ScheduleWork() { |
| 496 pump_->ScheduleWork(); | 477 pump_->ScheduleWork(); |
| 497 } | 478 } |
| 498 | 479 |
| 499 void MessageLoop::NotifyBeginNestedLoop() { | |
| 500 for (auto& observer : nesting_observers_) | |
| 501 observer.OnBeginNestedMessageLoop(); | |
| 502 } | |
| 503 | |
| 504 bool MessageLoop::DoWork() { | 480 bool MessageLoop::DoWork() { |
| 505 if (!nestable_tasks_allowed_) { | 481 if (!nestable_tasks_allowed_) { |
| 506 // Task can't be executed right now. | 482 // Task can't be executed right now. |
| 507 return false; | 483 return false; |
| 508 } | 484 } |
| 509 | 485 |
| 510 for (;;) { | 486 for (;;) { |
| 511 ReloadWorkQueue(); | 487 ReloadWorkQueue(); |
| 512 if (work_queue_.empty()) | 488 if (work_queue_.empty()) |
| 513 break; | 489 break; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 persistent, | 642 persistent, |
| 667 mode, | 643 mode, |
| 668 controller, | 644 controller, |
| 669 delegate); | 645 delegate); |
| 670 } | 646 } |
| 671 #endif | 647 #endif |
| 672 | 648 |
| 673 #endif // !defined(OS_NACL_SFI) | 649 #endif // !defined(OS_NACL_SFI) |
| 674 | 650 |
| 675 } // namespace base | 651 } // namespace base |
| OLD | NEW |