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 |