| 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 DCHECK_EQ(this, current()); | 205 DCHECK_EQ(this, current()); |
| 208 destruction_observers_.AddObserver(destruction_observer); | 206 destruction_observers_.AddObserver(destruction_observer); |
| 209 } | 207 } |
| 210 | 208 |
| 211 void MessageLoop::RemoveDestructionObserver( | 209 void MessageLoop::RemoveDestructionObserver( |
| 212 DestructionObserver* destruction_observer) { | 210 DestructionObserver* destruction_observer) { |
| 213 DCHECK_EQ(this, current()); | 211 DCHECK_EQ(this, current()); |
| 214 destruction_observers_.RemoveObserver(destruction_observer); | 212 destruction_observers_.RemoveObserver(destruction_observer); |
| 215 } | 213 } |
| 216 | 214 |
| 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() { | 215 void MessageLoop::QuitWhenIdle() { |
| 230 DCHECK_EQ(this, current()); | 216 DCHECK_EQ(this, current()); |
| 231 if (run_loop_) { | 217 if (run_loop_) { |
| 232 run_loop_->QuitWhenIdle(); | 218 run_loop_->QuitWhenIdle(); |
| 233 } else { | 219 } else { |
| 234 NOTREACHED() << "Must be inside Run to call QuitWhenIdle"; | 220 NOTREACHED() << "Must be inside Run to call QuitWhenIdle"; |
| 235 } | 221 } |
| 236 } | 222 } |
| 237 | 223 |
| 238 void MessageLoop::QuitNow() { | 224 void MessageLoop::QuitNow() { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 252 MessageLoop::current()->QuitWhenIdle(); | 238 MessageLoop::current()->QuitWhenIdle(); |
| 253 } | 239 } |
| 254 | 240 |
| 255 // static | 241 // static |
| 256 Closure MessageLoop::QuitWhenIdleClosure() { | 242 Closure MessageLoop::QuitWhenIdleClosure() { |
| 257 return Bind(&QuitCurrentWhenIdle); | 243 return Bind(&QuitCurrentWhenIdle); |
| 258 } | 244 } |
| 259 | 245 |
| 260 void MessageLoop::SetNestableTasksAllowed(bool allowed) { | 246 void MessageLoop::SetNestableTasksAllowed(bool allowed) { |
| 261 if (allowed) { | 247 if (allowed) { |
| 262 CHECK(allow_nesting_); | 248 CHECK(base::RunLoop::IsNestingAllowedOnCurrentThread()); |
| 263 | 249 |
| 264 // Kick the native pump just in case we enter a OS-driven nested message | 250 // Kick the native pump just in case we enter a OS-driven nested message |
| 265 // loop. | 251 // loop. |
| 266 pump_->ScheduleWork(); | 252 pump_->ScheduleWork(); |
| 267 } | 253 } |
| 268 nestable_tasks_allowed_ = allowed; | 254 nestable_tasks_allowed_ = allowed; |
| 269 } | 255 } |
| 270 | 256 |
| 271 bool MessageLoop::NestableTasksAllowed() const { | 257 bool MessageLoop::NestableTasksAllowed() const { |
| 272 return nestable_tasks_allowed_; | 258 return nestable_tasks_allowed_; |
| 273 } | 259 } |
| 274 | 260 |
| 275 bool MessageLoop::IsNested() { | 261 // TODO(gab): Migrate TaskObservers to RunLoop as part of separating concerns |
| 276 return run_loop_->run_depth_ > 1; | 262 // between MessageLoop and RunLoop and making MessageLoop a swappable |
| 277 } | 263 // implementation detail. http://crbug.com/703346 |
| 278 | |
| 279 void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { | 264 void MessageLoop::AddTaskObserver(TaskObserver* task_observer) { |
| 280 DCHECK_EQ(this, current()); | 265 DCHECK_EQ(this, current()); |
| 281 CHECK(allow_task_observers_); | 266 CHECK(allow_task_observers_); |
| 282 task_observers_.AddObserver(task_observer); | 267 task_observers_.AddObserver(task_observer); |
| 283 } | 268 } |
| 284 | 269 |
| 285 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { | 270 void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) { |
| 286 DCHECK_EQ(this, current()); | 271 DCHECK_EQ(this, current()); |
| 287 CHECK(allow_task_observers_); | 272 CHECK(allow_task_observers_); |
| 288 task_observers_.RemoveObserver(task_observer); | 273 task_observers_.RemoveObserver(task_observer); |
| 289 } | 274 } |
| 290 | 275 |
| 291 bool MessageLoop::is_running() const { | |
| 292 DCHECK_EQ(this, current()); | |
| 293 return run_loop_ != NULL; | |
| 294 } | |
| 295 | |
| 296 bool MessageLoop::HasHighResolutionTasks() { | 276 bool MessageLoop::HasHighResolutionTasks() { |
| 297 return incoming_task_queue_->HasHighResolutionTasks(); | 277 return incoming_task_queue_->HasHighResolutionTasks(); |
| 298 } | 278 } |
| 299 | 279 |
| 300 bool MessageLoop::IsIdleForTesting() { | 280 bool MessageLoop::IsIdleForTesting() { |
| 301 // We only check the incoming queue, since we don't want to lock the work | 281 // We only check the incoming queue, since we don't want to lock the work |
| 302 // queue. | 282 // queue. |
| 303 return incoming_task_queue_->IsIdleForTesting(); | 283 return incoming_task_queue_->IsIdleForTesting(); |
| 304 } | 284 } |
| 305 | 285 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 DCHECK_EQ(this, current()); | 356 DCHECK_EQ(this, current()); |
| 377 // Clear the previous thread task runner first, because only one can exist at | 357 // Clear the previous thread task runner first, because only one can exist at |
| 378 // a time. | 358 // a time. |
| 379 thread_task_runner_handle_.reset(); | 359 thread_task_runner_handle_.reset(); |
| 380 thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_)); | 360 thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_)); |
| 381 } | 361 } |
| 382 | 362 |
| 383 void MessageLoop::RunHandler() { | 363 void MessageLoop::RunHandler() { |
| 384 DCHECK_EQ(this, current()); | 364 DCHECK_EQ(this, current()); |
| 385 DCHECK(run_loop_); | 365 DCHECK(run_loop_); |
| 386 CHECK(allow_nesting_ || run_loop_->run_depth_ == 1); | |
| 387 pump_->Run(this); | 366 pump_->Run(this); |
| 388 } | 367 } |
| 389 | 368 |
| 390 bool MessageLoop::ProcessNextDelayedNonNestableTask() { | 369 bool MessageLoop::ProcessNextDelayedNonNestableTask() { |
| 391 if (run_loop_->run_depth_ != 1) | 370 if (is_nested_) |
| 392 return false; | 371 return false; |
| 393 | 372 |
| 394 if (deferred_non_nestable_work_queue_.empty()) | 373 if (deferred_non_nestable_work_queue_.empty()) |
| 395 return false; | 374 return false; |
| 396 | 375 |
| 397 PendingTask pending_task = | 376 PendingTask pending_task = |
| 398 std::move(deferred_non_nestable_work_queue_.front()); | 377 std::move(deferred_non_nestable_work_queue_.front()); |
| 399 deferred_non_nestable_work_queue_.pop(); | 378 deferred_non_nestable_work_queue_.pop(); |
| 400 | 379 |
| 401 RunTask(&pending_task); | 380 RunTask(&pending_task); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 423 task_annotator_.RunTask("MessageLoop::PostTask", pending_task); | 402 task_annotator_.RunTask("MessageLoop::PostTask", pending_task); |
| 424 for (auto& observer : task_observers_) | 403 for (auto& observer : task_observers_) |
| 425 observer.DidProcessTask(*pending_task); | 404 observer.DidProcessTask(*pending_task); |
| 426 | 405 |
| 427 nestable_tasks_allowed_ = true; | 406 nestable_tasks_allowed_ = true; |
| 428 | 407 |
| 429 current_pending_task_ = nullptr; | 408 current_pending_task_ = nullptr; |
| 430 } | 409 } |
| 431 | 410 |
| 432 bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) { | 411 bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) { |
| 433 if (pending_task.nestable || run_loop_->run_depth_ == 1) { | 412 if (pending_task.nestable || !is_nested_) { |
| 434 RunTask(&pending_task); | 413 RunTask(&pending_task); |
| 435 // Show that we ran a task (Note: a new one might arrive as a | 414 // Show that we ran a task (Note: a new one might arrive as a |
| 436 // consequence!). | 415 // consequence!). |
| 437 return true; | 416 return true; |
| 438 } | 417 } |
| 439 | 418 |
| 440 // We couldn't run the task now because we're in a nested message loop | 419 // We couldn't run the task now because we're in a nested message loop |
| 441 // and the task isn't nestable. | 420 // and the task isn't nestable. |
| 442 deferred_non_nestable_work_queue_.push(std::move(pending_task)); | 421 deferred_non_nestable_work_queue_.push(std::move(pending_task)); |
| 443 return false; | 422 return false; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 #else | 468 #else |
| 490 incoming_task_queue_->ReloadWorkQueue(&work_queue_); | 469 incoming_task_queue_->ReloadWorkQueue(&work_queue_); |
| 491 #endif | 470 #endif |
| 492 } | 471 } |
| 493 } | 472 } |
| 494 | 473 |
| 495 void MessageLoop::ScheduleWork() { | 474 void MessageLoop::ScheduleWork() { |
| 496 pump_->ScheduleWork(); | 475 pump_->ScheduleWork(); |
| 497 } | 476 } |
| 498 | 477 |
| 499 void MessageLoop::NotifyBeginNestedLoop() { | |
| 500 for (auto& observer : nesting_observers_) | |
| 501 observer.OnBeginNestedMessageLoop(); | |
| 502 } | |
| 503 | |
| 504 bool MessageLoop::DoWork() { | 478 bool MessageLoop::DoWork() { |
| 505 if (!nestable_tasks_allowed_) { | 479 if (!nestable_tasks_allowed_) { |
| 506 // Task can't be executed right now. | 480 // Task can't be executed right now. |
| 507 return false; | 481 return false; |
| 508 } | 482 } |
| 509 | 483 |
| 510 for (;;) { | 484 for (;;) { |
| 511 ReloadWorkQueue(); | 485 ReloadWorkQueue(); |
| 512 if (work_queue_.empty()) | 486 if (work_queue_.empty()) |
| 513 break; | 487 break; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 persistent, | 640 persistent, |
| 667 mode, | 641 mode, |
| 668 controller, | 642 controller, |
| 669 delegate); | 643 delegate); |
| 670 } | 644 } |
| 671 #endif | 645 #endif |
| 672 | 646 |
| 673 #endif // !defined(OS_NACL_SFI) | 647 #endif // !defined(OS_NACL_SFI) |
| 674 | 648 |
| 675 } // namespace base | 649 } // namespace base |
| OLD | NEW |