Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: base/message_loop.h

Issue 8565024: base: Refactor PendingTask out of MessageLoop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add new files. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_H_ 5 #ifndef BASE_MESSAGE_LOOP_H_
6 #define BASE_MESSAGE_LOOP_H_ 6 #define BASE_MESSAGE_LOOP_H_
7 #pragma once 7 #pragma once
8 8
9 #include <queue> 9 #include <queue>
10 #include <string> 10 #include <string>
11 11
12 #include "base/base_export.h" 12 #include "base/base_export.h"
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/location.h" 15 #include "base/location.h"
16 #include "base/memory/ref_counted.h" 16 #include "base/memory/ref_counted.h"
17 #include "base/message_loop_proxy.h" 17 #include "base/message_loop_proxy.h"
18 #include "base/message_pump.h" 18 #include "base/message_pump.h"
19 #include "base/observer_list.h" 19 #include "base/observer_list.h"
20 #include "base/pending_task.h"
20 #include "base/synchronization/lock.h" 21 #include "base/synchronization/lock.h"
21 #include "base/task.h" 22 #include "base/task.h"
22 #include "base/tracking_info.h" 23 #include "base/tracking_info.h"
23 #include "base/time.h" 24 #include "base/time.h"
24 25
25 #if defined(OS_WIN) 26 #if defined(OS_WIN)
26 // We need this to declare base::MessagePumpWin::Dispatcher, which we should 27 // We need this to declare base::MessagePumpWin::Dispatcher, which we should
27 // really just eliminate. 28 // really just eliminate.
28 #include "base/message_pump_win.h" 29 #include "base/message_pump_win.h"
29 #elif defined(OS_POSIX) 30 #elif defined(OS_POSIX)
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 static MessageLoop* current(); 119 static MessageLoop* current();
119 120
120 static void EnableHistogrammer(bool enable_histogrammer); 121 static void EnableHistogrammer(bool enable_histogrammer);
121 122
122 typedef base::MessagePump* (MessagePumpFactory)(); 123 typedef base::MessagePump* (MessagePumpFactory)();
123 // Using the given base::MessagePumpForUIFactory to override the default 124 // Using the given base::MessagePumpForUIFactory to override the default
124 // MessagePump implementation for 'TYPE_UI'. 125 // MessagePump implementation for 'TYPE_UI'.
125 static void InitMessagePumpForUIFactory(MessagePumpFactory* factory); 126 static void InitMessagePumpForUIFactory(MessagePumpFactory* factory);
126 127
127 // A DestructionObserver is notified when the current MessageLoop is being 128 // A DestructionObserver is notified when the current MessageLoop is being
128 // destroyed. These obsevers are notified prior to MessageLoop::current() 129 // destroyed. These observers are notified prior to MessageLoop::current()
129 // being changed to return NULL. This gives interested parties the chance to 130 // being changed to return NULL. This gives interested parties the chance to
130 // do final cleanup that depends on the MessageLoop. 131 // do final cleanup that depends on the MessageLoop.
131 // 132 //
132 // NOTE: Any tasks posted to the MessageLoop during this notification will 133 // NOTE: Any tasks posted to the MessageLoop during this notification will
133 // not be run. Instead, they will be deleted. 134 // not be run. Instead, they will be deleted.
134 // 135 //
135 class BASE_EXPORT DestructionObserver { 136 class BASE_EXPORT DestructionObserver {
136 public: 137 public:
137 virtual void WillDestroyCurrentMessageLoop() = 0; 138 virtual void WillDestroyCurrentMessageLoop() = 0;
138 139
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 explicit AutoRunState(MessageLoop* loop); 405 explicit AutoRunState(MessageLoop* loop);
405 ~AutoRunState(); 406 ~AutoRunState();
406 private: 407 private:
407 MessageLoop* loop_; 408 MessageLoop* loop_;
408 RunState* previous_state_; 409 RunState* previous_state_;
409 }; 410 };
410 #if defined(OS_ANDROID) 411 #if defined(OS_ANDROID)
411 protected: 412 protected:
412 #endif 413 #endif
413 414
414 // This structure is copied around by value.
415 struct PendingTask : public base::TrackingInfo {
416 PendingTask(const base::Closure& task,
417 const tracked_objects::Location& posted_from,
418 base::TimeTicks delayed_run_time,
419 bool nestable);
420 ~PendingTask();
421
422 // Used to support sorting.
423 bool operator<(const PendingTask& other) const;
424
425 // The task to run.
426 base::Closure task;
427
428 // The site this PendingTask was posted from.
429 tracked_objects::Location posted_from;
430
431 // Secondary sort key for run time.
432 int sequence_num;
433
434 // OK to dispatch from a nested loop.
435 bool nestable;
436 };
437
438 class TaskQueue : public std::queue<PendingTask> {
439 public:
440 void Swap(TaskQueue* queue) {
441 c.swap(queue->c); // Calls std::deque::swap
442 }
443 };
444
445 typedef std::priority_queue<PendingTask> DelayedTaskQueue;
446
447 #if defined(OS_WIN) 415 #if defined(OS_WIN)
448 base::MessagePumpWin* pump_win() { 416 base::MessagePumpWin* pump_win() {
449 return static_cast<base::MessagePumpWin*>(pump_.get()); 417 return static_cast<base::MessagePumpWin*>(pump_.get());
450 } 418 }
451 #elif defined(OS_POSIX) 419 #elif defined(OS_POSIX)
452 base::MessagePumpLibevent* pump_libevent() { 420 base::MessagePumpLibevent* pump_libevent() {
453 return static_cast<base::MessagePumpLibevent*>(pump_.get()); 421 return static_cast<base::MessagePumpLibevent*>(pump_.get());
454 } 422 }
455 #endif 423 #endif
456 424
457 // A function to encapsulate all the exception handling capability in the 425 // A function to encapsulate all the exception handling capability in the
458 // stacks around the running of a main message loop. It will run the message 426 // stacks around the running of a main message loop. It will run the message
459 // loop in a SEH try block or not depending on the set_SEH_restoration() 427 // loop in a SEH try block or not depending on the set_SEH_restoration()
460 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). 428 // flag invoking respectively RunInternalInSEHFrame() or RunInternal().
461 void RunHandler(); 429 void RunHandler();
462 430
463 #if defined(OS_WIN) 431 #if defined(OS_WIN)
464 __declspec(noinline) void RunInternalInSEHFrame(); 432 __declspec(noinline) void RunInternalInSEHFrame();
465 #endif 433 #endif
466 434
467 // A surrounding stack frame around the running of the message loop that 435 // A surrounding stack frame around the running of the message loop that
468 // supports all saving and restoring of state, as is needed for any/all (ugly) 436 // supports all saving and restoring of state, as is needed for any/all (ugly)
469 // recursive calls. 437 // recursive calls.
470 void RunInternal(); 438 void RunInternal();
471 439
472 // Called to process any delayed non-nestable tasks. 440 // Called to process any delayed non-nestable tasks.
473 bool ProcessNextDelayedNonNestableTask(); 441 bool ProcessNextDelayedNonNestableTask();
474 442
475 // Runs the specified PendingTask. 443 // Runs the specified PendingTask.
476 void RunTask(const PendingTask& pending_task); 444 void RunTask(const base::PendingTask& pending_task);
477 445
478 // Calls RunTask or queues the pending_task on the deferred task list if it 446 // Calls RunTask or queues the pending_task on the deferred task list if it
479 // cannot be run right now. Returns true if the task was run. 447 // cannot be run right now. Returns true if the task was run.
480 bool DeferOrRunPendingTask(const PendingTask& pending_task); 448 bool DeferOrRunPendingTask(const base::PendingTask& pending_task);
481 449
482 // Adds the pending task to delayed_work_queue_. 450 // Adds the pending task to delayed_work_queue_.
483 void AddToDelayedWorkQueue(const PendingTask& pending_task); 451 void AddToDelayedWorkQueue(const base::PendingTask& pending_task);
484 452
485 // Adds the pending task to our incoming_queue_. 453 // Adds the pending task to our incoming_queue_.
486 // 454 //
487 // Caller retains ownership of |pending_task|, but this function will 455 // Caller retains ownership of |pending_task|, but this function will
488 // reset the value of pending_task->task. This is needed to ensure 456 // reset the value of pending_task->task. This is needed to ensure
489 // that the posting call stack does not retain pending_task->task 457 // that the posting call stack does not retain pending_task->task
490 // beyond this function call. 458 // beyond this function call.
491 void AddToIncomingQueue(PendingTask* pending_task); 459 void AddToIncomingQueue(base::PendingTask* pending_task);
492 460
493 // Load tasks from the incoming_queue_ into work_queue_ if the latter is 461 // Load tasks from the incoming_queue_ into work_queue_ if the latter is
494 // empty. The former requires a lock to access, while the latter is directly 462 // empty. The former requires a lock to access, while the latter is directly
495 // accessible on this thread. 463 // accessible on this thread.
496 void ReloadWorkQueue(); 464 void ReloadWorkQueue();
497 465
498 // Delete tasks that haven't run yet without running them. Used in the 466 // Delete tasks that haven't run yet without running them. Used in the
499 // destructor to make sure all the task's destructors get called. Returns 467 // destructor to make sure all the task's destructors get called. Returns
500 // true if some work was done. 468 // true if some work was done.
501 bool DeletePendingTasks(); 469 bool DeletePendingTasks();
502 470
503 // Calcuates the time at which a PendingTask should run. 471 // Calculates the time at which a PendingTask should run.
504 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms); 472 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms);
505 473
506 // Start recording histogram info about events and action IF it was enabled 474 // Start recording histogram info about events and action IF it was enabled
507 // and IF the statistics recorder can accept a registration of our histogram. 475 // and IF the statistics recorder can accept a registration of our histogram.
508 void StartHistogrammer(); 476 void StartHistogrammer();
509 477
510 // Add occurence of event to our histogram, so that we can see what is being 478 // Add occurrence of event to our histogram, so that we can see what is being
511 // done in a specific MessageLoop instance (i.e., specific thread). 479 // done in a specific MessageLoop instance (i.e., specific thread).
512 // If message_histogram_ is NULL, this is a no-op. 480 // If message_histogram_ is NULL, this is a no-op.
513 void HistogramEvent(int event); 481 void HistogramEvent(int event);
514 482
515 // base::MessagePump::Delegate methods: 483 // base::MessagePump::Delegate methods:
516 virtual bool DoWork(); 484 virtual bool DoWork();
517 virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time); 485 virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time);
518 virtual bool DoIdleWork(); 486 virtual bool DoIdleWork();
519 487
520 Type type_; 488 Type type_;
521 489
522 // A list of tasks that need to be processed by this instance. Note that 490 // A list of tasks that need to be processed by this instance. Note that
523 // this queue is only accessed (push/pop) by our current thread. 491 // this queue is only accessed (push/pop) by our current thread.
524 TaskQueue work_queue_; 492 base::TaskQueue work_queue_;
525 493
526 // Contains delayed tasks, sorted by their 'delayed_run_time' property. 494 // Contains delayed tasks, sorted by their 'delayed_run_time' property.
527 DelayedTaskQueue delayed_work_queue_; 495 base::DelayedTaskQueue delayed_work_queue_;
528 496
529 // A recent snapshot of Time::Now(), used to check delayed_work_queue_. 497 // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
530 base::TimeTicks recent_time_; 498 base::TimeTicks recent_time_;
531 499
532 // A queue of non-nestable tasks that we had to defer because when it came 500 // A queue of non-nestable tasks that we had to defer because when it came
533 // time to execute them we were in a nested message loop. They will execute 501 // time to execute them we were in a nested message loop. They will execute
534 // once we're out of nested message loops. 502 // once we're out of nested message loops.
535 TaskQueue deferred_non_nestable_work_queue_; 503 base::TaskQueue deferred_non_nestable_work_queue_;
536 504
537 scoped_refptr<base::MessagePump> pump_; 505 scoped_refptr<base::MessagePump> pump_;
538 506
539 ObserverList<DestructionObserver> destruction_observers_; 507 ObserverList<DestructionObserver> destruction_observers_;
540 508
541 // A recursion block that prevents accidentally running additonal tasks when 509 // A recursion block that prevents accidentally running additional tasks when
542 // insider a (accidentally induced?) nested message pump. 510 // insider a (accidentally induced?) nested message pump.
543 bool nestable_tasks_allowed_; 511 bool nestable_tasks_allowed_;
544 512
545 bool exception_restoration_; 513 bool exception_restoration_;
546 514
547 std::string thread_name_; 515 std::string thread_name_;
548 // A profiling histogram showing the counts of various messages and events. 516 // A profiling histogram showing the counts of various messages and events.
549 base::Histogram* message_histogram_; 517 base::Histogram* message_histogram_;
550 518
551 // A null terminated list which creates an incoming_queue of tasks that are 519 // A null terminated list which creates an incoming_queue of tasks that are
552 // acquired under a mutex for processing on this instance's thread. These 520 // acquired under a mutex for processing on this instance's thread. These
553 // tasks have not yet been sorted out into items for our work_queue_ vs items 521 // tasks have not yet been sorted out into items for our work_queue_ vs items
554 // that will be handled by the TimerManager. 522 // that will be handled by the TimerManager.
555 TaskQueue incoming_queue_; 523 base::TaskQueue incoming_queue_;
556 // Protect access to incoming_queue_. 524 // Protect access to incoming_queue_.
557 mutable base::Lock incoming_queue_lock_; 525 mutable base::Lock incoming_queue_lock_;
558 526
559 RunState* state_; 527 RunState* state_;
560 528
561 // The need for this variable is subtle. Please see implementation comments 529 // The need for this variable is subtle. Please see implementation comments
562 // around where it is used. 530 // around where it is used.
563 bool should_leak_tasks_; 531 bool should_leak_tasks_;
564 532
565 #if defined(OS_WIN) 533 #if defined(OS_WIN)
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 #endif // defined(OS_POSIX) 670 #endif // defined(OS_POSIX)
703 }; 671 };
704 672
705 // Do not add any member variables to MessageLoopForIO! This is important b/c 673 // Do not add any member variables to MessageLoopForIO! This is important b/c
706 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra 674 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra
707 // data that you need should be stored on the MessageLoop's pump_ instance. 675 // data that you need should be stored on the MessageLoop's pump_ instance.
708 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), 676 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
709 MessageLoopForIO_should_not_have_extra_member_variables); 677 MessageLoopForIO_should_not_have_extra_member_variables);
710 678
711 #endif // BASE_MESSAGE_LOOP_H_ 679 #endif // BASE_MESSAGE_LOOP_H_
OLDNEW
« no previous file with comments | « base/base.gypi ('k') | base/message_loop.cc » ('j') | base/pending_task.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698