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 #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ | 5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ |
| 6 #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ | 6 #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ |
| 7 | 7 |
| 8 #include <queue> | 8 #include <queue> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/base_export.h" | 11 #include "base/base_export.h" |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/callback_forward.h" | 13 #include "base/callback_forward.h" |
| 14 #include "base/location.h" | 14 #include "base/location.h" |
| 15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 16 #include "base/memory/scoped_ptr.h" | |
| 16 #include "base/message_loop/message_loop_proxy.h" | 17 #include "base/message_loop/message_loop_proxy.h" |
| 17 #include "base/message_loop/message_pump.h" | 18 #include "base/message_loop/message_pump.h" |
| 18 #include "base/observer_list.h" | 19 #include "base/observer_list.h" |
| 19 #include "base/pending_task.h" | 20 #include "base/pending_task.h" |
| 20 #include "base/sequenced_task_runner_helpers.h" | 21 #include "base/sequenced_task_runner_helpers.h" |
| 21 #include "base/synchronization/lock.h" | 22 #include "base/synchronization/lock.h" |
| 22 #include "base/time/time.h" | 23 #include "base/time/time.h" |
| 23 #include "base/tracking_info.h" | 24 #include "base/tracking_info.h" |
| 24 | 25 |
| 25 #if defined(OS_WIN) | 26 #if defined(OS_WIN) |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 Type type() const { return type_; } | 276 Type type() const { return type_; } |
| 276 | 277 |
| 277 // Optional call to connect the thread name with this loop. | 278 // Optional call to connect the thread name with this loop. |
| 278 void set_thread_name(const std::string& thread_name) { | 279 void set_thread_name(const std::string& thread_name) { |
| 279 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; | 280 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; |
| 280 thread_name_ = thread_name; | 281 thread_name_ = thread_name; |
| 281 } | 282 } |
| 282 const std::string& thread_name() const { return thread_name_; } | 283 const std::string& thread_name() const { return thread_name_; } |
| 283 | 284 |
| 284 // Gets the message loop proxy associated with this message loop. | 285 // Gets the message loop proxy associated with this message loop. |
| 285 scoped_refptr<MessageLoopProxy> message_loop_proxy() { | 286 scoped_refptr<MessageLoopProxy> message_loop_proxy(); |
|
DaleCurtis
2013/07/10 17:31:08
OOC, why? This is a simple getter. Per style guide
alexeypa (please no reviews)
2013/07/10 19:39:59
Including message_loop_proxy_impl.h to message_loo
DaleCurtis
2013/07/10 19:52:43
This is because you've defined ProxyImpl as a nest
alexeypa (please no reviews)
2013/07/10 20:05:27
No, it is because ProxyImpl (and MessageLoopProxyI
alexeypa (please no reviews)
2013/07/10 21:01:13
We discussed this issue offline and it seems that
| |
| 286 return message_loop_proxy_.get(); | |
| 287 } | |
| 288 | 287 |
| 289 // Enables or disables the recursive task processing. This happens in the case | 288 // Enables or disables the recursive task processing. This happens in the case |
| 290 // of recursive message loops. Some unwanted message loop may occurs when | 289 // of recursive message loops. Some unwanted message loop may occurs when |
| 291 // using common controls or printer functions. By default, recursive task | 290 // using common controls or printer functions. By default, recursive task |
| 292 // processing is disabled. | 291 // processing is disabled. |
| 293 // | 292 // |
| 294 // Please utilize |ScopedNestableTaskAllower| instead of calling these methods | 293 // Please utilize |ScopedNestableTaskAllower| instead of calling these methods |
| 295 // directly. In general nestable message loops are to be avoided. They are | 294 // directly. In general nestable message loops are to be avoided. They are |
| 296 // dangerous and difficult to get right, so please use with extreme caution. | 295 // dangerous and difficult to get right, so please use with extreme caution. |
| 297 // | 296 // |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 | 351 |
| 353 protected: | 352 protected: |
| 354 virtual ~TaskObserver(); | 353 virtual ~TaskObserver(); |
| 355 }; | 354 }; |
| 356 | 355 |
| 357 // These functions can only be called on the same thread that |this| is | 356 // These functions can only be called on the same thread that |this| is |
| 358 // running on. | 357 // running on. |
| 359 void AddTaskObserver(TaskObserver* task_observer); | 358 void AddTaskObserver(TaskObserver* task_observer); |
| 360 void RemoveTaskObserver(TaskObserver* task_observer); | 359 void RemoveTaskObserver(TaskObserver* task_observer); |
| 361 | 360 |
| 362 // Returns true if the message loop has high resolution timers enabled. | |
| 363 // Provided for testing. | |
| 364 bool high_resolution_timers_enabled() { | |
| 365 #if defined(OS_WIN) | |
| 366 return !high_resolution_timer_expiration_.is_null(); | |
| 367 #else | |
| 368 return true; | |
| 369 #endif | |
| 370 } | |
| 371 | |
| 372 // When we go into high resolution timer mode, we will stay in hi-res mode | 361 // When we go into high resolution timer mode, we will stay in hi-res mode |
| 373 // for at least 1s. | 362 // for at least 1s. |
| 374 static const int kHighResolutionTimerModeLeaseTimeMs = 1000; | 363 static const int kHighResolutionTimerModeLeaseTimeMs = 1000; |
| 375 | 364 |
| 376 // Asserts that the MessageLoop is "idle". | |
| 377 void AssertIdle() const; | |
| 378 | |
| 379 #if defined(OS_WIN) | 365 #if defined(OS_WIN) |
| 380 void set_os_modal_loop(bool os_modal_loop) { | 366 void set_os_modal_loop(bool os_modal_loop) { |
| 381 os_modal_loop_ = os_modal_loop; | 367 os_modal_loop_ = os_modal_loop; |
| 382 } | 368 } |
| 383 | 369 |
| 384 bool os_modal_loop() const { | 370 bool os_modal_loop() const { |
| 385 return os_modal_loop_; | 371 return os_modal_loop_; |
| 386 } | 372 } |
| 387 #endif // OS_WIN | 373 #endif // OS_WIN |
| 388 | 374 |
| 389 // Can only be called from the thread that owns the MessageLoop. | 375 // Can only be called from the thread that owns the MessageLoop. |
| 390 bool is_running() const; | 376 bool is_running() const; |
| 391 | 377 |
| 378 // Returns true if the message loop has high resolution timers enabled. | |
| 379 // Provided for testing. | |
| 380 bool IsHishResolutionTimersEnabledForTest(); | |
|
DaleCurtis
2013/07/10 17:31:08
s/Hish/High/ s/Timers/Timer/ ?
alexeypa (please no reviews)
2013/07/10 19:39:59
Done.
| |
| 381 | |
| 382 // Returns true if the message loop is "idle". Provided for testing. | |
| 383 bool IsIdleForTest(); | |
| 384 | |
| 392 //---------------------------------------------------------------------------- | 385 //---------------------------------------------------------------------------- |
| 393 protected: | 386 protected: |
| 394 | 387 |
| 395 #if defined(OS_WIN) | 388 #if defined(OS_WIN) |
| 396 MessagePumpWin* pump_win() { | 389 MessagePumpWin* pump_win() { |
| 397 return static_cast<MessagePumpWin*>(pump_.get()); | 390 return static_cast<MessagePumpWin*>(pump_.get()); |
| 398 } | 391 } |
| 399 #elif defined(OS_POSIX) && !defined(OS_IOS) | 392 #elif defined(OS_POSIX) && !defined(OS_IOS) |
| 400 MessagePumpLibevent* pump_libevent() { | 393 MessagePumpLibevent* pump_libevent() { |
| 401 return static_cast<MessagePumpLibevent*>(pump_.get()); | 394 return static_cast<MessagePumpLibevent*>(pump_.get()); |
| 402 } | 395 } |
| 403 #endif | 396 #endif |
| 404 | 397 |
| 405 scoped_refptr<MessagePump> pump_; | 398 scoped_ptr<MessagePump> pump_; |
| 406 | 399 |
| 407 private: | 400 private: |
| 401 class ProxyImpl; | |
| 402 | |
| 403 friend class MessageLoopLockTest; | |
| 404 friend class ProxyImpl; | |
| 408 friend class RunLoop; | 405 friend class RunLoop; |
| 409 friend class MessageLoopLockTest; | |
| 410 | 406 |
| 411 // A function to encapsulate all the exception handling capability in the | 407 // A function to encapsulate all the exception handling capability in the |
| 412 // stacks around the running of a main message loop. It will run the message | 408 // stacks around the running of a main message loop. It will run the message |
| 413 // loop in a SEH try block or not depending on the set_SEH_restoration() | 409 // loop in a SEH try block or not depending on the set_SEH_restoration() |
| 414 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). | 410 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). |
| 415 void RunHandler(); | 411 void RunHandler(); |
| 416 | 412 |
| 417 #if defined(OS_WIN) | 413 #if defined(OS_WIN) |
| 418 __declspec(noinline) void RunInternalInSEHFrame(); | 414 __declspec(noinline) void RunInternalInSEHFrame(); |
| 419 #endif | 415 #endif |
| 420 | 416 |
| 421 // A surrounding stack frame around the running of the message loop that | 417 // A surrounding stack frame around the running of the message loop that |
| 422 // supports all saving and restoring of state, as is needed for any/all (ugly) | 418 // supports all saving and restoring of state, as is needed for any/all (ugly) |
| 423 // recursive calls. | 419 // recursive calls. |
| 424 void RunInternal(); | 420 void RunInternal(); |
| 425 | 421 |
| 426 // Called to process any delayed non-nestable tasks. | 422 // Called to process any delayed non-nestable tasks. |
| 427 bool ProcessNextDelayedNonNestableTask(); | 423 bool ProcessNextDelayedNonNestableTask(); |
| 428 | 424 |
| 429 // Runs the specified PendingTask. | 425 // Runs the specified PendingTask. |
| 430 void RunTask(const PendingTask& pending_task); | 426 void RunTask(const PendingTask& pending_task); |
| 431 | 427 |
| 432 // Calls RunTask or queues the pending_task on the deferred task list if it | 428 // Calls RunTask or queues the pending_task on the deferred task list if it |
| 433 // cannot be run right now. Returns true if the task was run. | 429 // cannot be run right now. Returns true if the task was run. |
| 434 bool DeferOrRunPendingTask(const PendingTask& pending_task); | 430 bool DeferOrRunPendingTask(const PendingTask& pending_task); |
| 435 | 431 |
| 436 // Adds the pending task to delayed_work_queue_. | 432 // Adds the pending task to delayed_work_queue_. |
| 437 void AddToDelayedWorkQueue(const PendingTask& pending_task); | 433 void AddToDelayedWorkQueue(const PendingTask& pending_task); |
| 438 | 434 |
| 439 // This function attempts to add pending task to our incoming_queue_. | |
| 440 // The append can only possibly fail when |use_try_lock| is true. | |
| 441 // | |
| 442 // When |use_try_lock| is true, then this call will avoid blocking if | |
| 443 // the related lock is already held, and will in that case (when the | |
| 444 // lock is contended) fail to perform the append, and will return false. | |
| 445 // | |
| 446 // If the call succeeds to append to the queue, then this call | |
| 447 // will return true. | |
| 448 // | |
| 449 // In all cases, the caller retains ownership of |pending_task|, but this | |
| 450 // function will reset the value of pending_task->task. This is needed to | |
| 451 // ensure that the posting call stack does not retain pending_task->task | |
| 452 // beyond this function call. | |
| 453 bool AddToIncomingQueue(PendingTask* pending_task, bool use_try_lock); | |
| 454 | |
| 455 // Load tasks from the incoming_queue_ into work_queue_ if the latter is | |
| 456 // empty. The former requires a lock to access, while the latter is directly | |
| 457 // accessible on this thread. | |
| 458 void ReloadWorkQueue(); | |
| 459 | |
| 460 // Delete tasks that haven't run yet without running them. Used in the | 435 // Delete tasks that haven't run yet without running them. Used in the |
| 461 // destructor to make sure all the task's destructors get called. Returns | 436 // destructor to make sure all the task's destructors get called. Returns |
| 462 // true if some work was done. | 437 // true if some work was done. |
| 463 bool DeletePendingTasks(); | 438 bool DeletePendingTasks(); |
| 464 | 439 |
| 465 // Calculates the time at which a PendingTask should run. | 440 // Creates a process-wide unique ID to represent this task in trace events. |
| 466 TimeTicks CalculateDelayedRuntime(TimeDelta delay); | 441 // This will be mangled with a Process ID hash to reduce the likelyhood of |
| 442 // colliding with MessageLoop pointers on other processes. | |
| 443 uint64 GetTaskTraceID(const PendingTask& task); | |
| 444 | |
| 445 // Loads tasks from the incoming queue to |work_queue_| if the latter is | |
| 446 // empty. | |
| 447 void ReloadWorkQueue(); | |
| 448 | |
| 449 // Wakes up the message pump. Can be called on any thread. The caller is | |
| 450 // responsible for synchronizing WakeUpPump() calls. | |
| 451 void WakeUpPump(); | |
| 467 | 452 |
| 468 // Start recording histogram info about events and action IF it was enabled | 453 // Start recording histogram info about events and action IF it was enabled |
| 469 // and IF the statistics recorder can accept a registration of our histogram. | 454 // and IF the statistics recorder can accept a registration of our histogram. |
| 470 void StartHistogrammer(); | 455 void StartHistogrammer(); |
| 471 | 456 |
| 472 // Add occurrence of event to our histogram, so that we can see what is being | 457 // Add occurrence of event to our histogram, so that we can see what is being |
| 473 // done in a specific MessageLoop instance (i.e., specific thread). | 458 // done in a specific MessageLoop instance (i.e., specific thread). |
| 474 // If message_histogram_ is NULL, this is a no-op. | 459 // If message_histogram_ is NULL, this is a no-op. |
| 475 void HistogramEvent(int event); | 460 void HistogramEvent(int event); |
| 476 | 461 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 491 // A recent snapshot of Time::Now(), used to check delayed_work_queue_. | 476 // A recent snapshot of Time::Now(), used to check delayed_work_queue_. |
| 492 TimeTicks recent_time_; | 477 TimeTicks recent_time_; |
| 493 | 478 |
| 494 // A queue of non-nestable tasks that we had to defer because when it came | 479 // A queue of non-nestable tasks that we had to defer because when it came |
| 495 // time to execute them we were in a nested message loop. They will execute | 480 // time to execute them we were in a nested message loop. They will execute |
| 496 // once we're out of nested message loops. | 481 // once we're out of nested message loops. |
| 497 TaskQueue deferred_non_nestable_work_queue_; | 482 TaskQueue deferred_non_nestable_work_queue_; |
| 498 | 483 |
| 499 ObserverList<DestructionObserver> destruction_observers_; | 484 ObserverList<DestructionObserver> destruction_observers_; |
| 500 | 485 |
| 486 bool exception_restoration_; | |
| 487 | |
| 501 // A recursion block that prevents accidentally running additional tasks when | 488 // A recursion block that prevents accidentally running additional tasks when |
| 502 // insider a (accidentally induced?) nested message pump. | 489 // insider a (accidentally induced?) nested message pump. |
| 503 bool nestable_tasks_allowed_; | 490 bool nestable_tasks_allowed_; |
| 504 | 491 |
| 505 bool exception_restoration_; | 492 #if defined(OS_WIN) |
| 493 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc | |
| 494 // which enter a modal message loop. | |
| 495 bool os_modal_loop_; | |
| 496 #endif | |
| 506 | 497 |
| 507 std::string thread_name_; | 498 std::string thread_name_; |
| 508 // A profiling histogram showing the counts of various messages and events. | 499 // A profiling histogram showing the counts of various messages and events. |
| 509 HistogramBase* message_histogram_; | 500 HistogramBase* message_histogram_; |
| 510 | 501 |
| 511 // An incoming queue of tasks that are acquired under a mutex for processing | |
| 512 // on this instance's thread. These tasks have not yet been sorted out into | |
| 513 // items for our work_queue_ vs delayed_work_queue_. | |
| 514 TaskQueue incoming_queue_; | |
| 515 // Protect access to incoming_queue_. | |
| 516 mutable Lock incoming_queue_lock_; | |
| 517 | |
| 518 RunLoop* run_loop_; | 502 RunLoop* run_loop_; |
| 519 | 503 |
| 520 #if defined(OS_WIN) | |
| 521 TimeTicks high_resolution_timer_expiration_; | |
| 522 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc | |
| 523 // which enter a modal message loop. | |
| 524 bool os_modal_loop_; | |
| 525 #endif | |
| 526 | |
| 527 // The next sequence number to use for delayed tasks. Updating this counter is | |
| 528 // protected by incoming_queue_lock_. | |
| 529 int next_sequence_num_; | |
| 530 | |
| 531 ObserverList<TaskObserver> task_observers_; | 504 ObserverList<TaskObserver> task_observers_; |
| 532 | 505 |
| 533 // The message loop proxy associated with this message loop, if one exists. | 506 // The message loop proxy associated with this message loop. |
| 534 scoped_refptr<MessageLoopProxy> message_loop_proxy_; | 507 scoped_refptr<ProxyImpl> message_loop_proxy_; |
| 535 scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_; | 508 scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_; |
| 536 | 509 |
| 537 template <class T, class R> friend class base::subtle::DeleteHelperInternal; | 510 template <class T, class R> friend class base::subtle::DeleteHelperInternal; |
| 538 template <class T, class R> friend class base::subtle::ReleaseHelperInternal; | 511 template <class T, class R> friend class base::subtle::ReleaseHelperInternal; |
| 539 | 512 |
| 540 void DeleteSoonInternal(const tracked_objects::Location& from_here, | 513 void DeleteSoonInternal(const tracked_objects::Location& from_here, |
| 541 void(*deleter)(const void*), | 514 void(*deleter)(const void*), |
| 542 const void* object); | 515 const void* object); |
| 543 void ReleaseSoonInternal(const tracked_objects::Location& from_here, | 516 void ReleaseSoonInternal(const tracked_objects::Location& from_here, |
| 544 void(*releaser)(const void*), | 517 void(*releaser)(const void*), |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 720 | 693 |
| 721 // Do not add any member variables to MessageLoopForIO! This is important b/c | 694 // Do not add any member variables to MessageLoopForIO! This is important b/c |
| 722 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 695 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
| 723 // data that you need should be stored on the MessageLoop's pump_ instance. | 696 // data that you need should be stored on the MessageLoop's pump_ instance. |
| 724 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 697 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
| 725 MessageLoopForIO_should_not_have_extra_member_variables); | 698 MessageLoopForIO_should_not_have_extra_member_variables); |
| 726 | 699 |
| 727 } // namespace base | 700 } // namespace base |
| 728 | 701 |
| 729 #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ | 702 #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ |
| OLD | NEW |