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

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: Review fixes. 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
« no previous file with comments | « base/base.gypi ('k') | base/message_loop.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 static MessageLoop* current(); 115 static MessageLoop* current();
115 116
116 static void EnableHistogrammer(bool enable_histogrammer); 117 static void EnableHistogrammer(bool enable_histogrammer);
117 118
118 typedef base::MessagePump* (MessagePumpFactory)(); 119 typedef base::MessagePump* (MessagePumpFactory)();
119 // Using the given base::MessagePumpForUIFactory to override the default 120 // Using the given base::MessagePumpForUIFactory to override the default
120 // MessagePump implementation for 'TYPE_UI'. 121 // MessagePump implementation for 'TYPE_UI'.
121 static void InitMessagePumpForUIFactory(MessagePumpFactory* factory); 122 static void InitMessagePumpForUIFactory(MessagePumpFactory* factory);
122 123
123 // A DestructionObserver is notified when the current MessageLoop is being 124 // A DestructionObserver is notified when the current MessageLoop is being
124 // destroyed. These obsevers are notified prior to MessageLoop::current() 125 // destroyed. These observers are notified prior to MessageLoop::current()
125 // being changed to return NULL. This gives interested parties the chance to 126 // being changed to return NULL. This gives interested parties the chance to
126 // do final cleanup that depends on the MessageLoop. 127 // do final cleanup that depends on the MessageLoop.
127 // 128 //
128 // NOTE: Any tasks posted to the MessageLoop during this notification will 129 // NOTE: Any tasks posted to the MessageLoop during this notification will
129 // not be run. Instead, they will be deleted. 130 // not be run. Instead, they will be deleted.
130 // 131 //
131 class BASE_EXPORT DestructionObserver { 132 class BASE_EXPORT DestructionObserver {
132 public: 133 public:
133 virtual void WillDestroyCurrentMessageLoop() = 0; 134 virtual void WillDestroyCurrentMessageLoop() = 0;
134 135
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 bool os_modal_loop() const { 371 bool os_modal_loop() const {
371 return os_modal_loop_; 372 return os_modal_loop_;
372 } 373 }
373 #endif // OS_WIN 374 #endif // OS_WIN
374 375
375 // Can only be called from the thread that owns the MessageLoop. 376 // Can only be called from the thread that owns the MessageLoop.
376 bool is_running() const; 377 bool is_running() const;
377 378
378 //---------------------------------------------------------------------------- 379 //----------------------------------------------------------------------------
379 protected: 380 protected:
381 // PendingTasks are sorted by their |delayed_run_time| property.
382 typedef std::priority_queue<base::PendingTask> DelayedTaskQueue;
383
380 struct RunState { 384 struct RunState {
381 // Used to count how many Run() invocations are on the stack. 385 // Used to count how many Run() invocations are on the stack.
382 int run_depth; 386 int run_depth;
383 387
384 // Used to record that Quit() was called, or that we should quit the pump 388 // Used to record that Quit() was called, or that we should quit the pump
385 // once it becomes idle. 389 // once it becomes idle.
386 bool quit_received; 390 bool quit_received;
387 391
388 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) 392 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
389 Dispatcher* dispatcher; 393 Dispatcher* dispatcher;
(...skipping 10 matching lines...) Expand all
400 explicit AutoRunState(MessageLoop* loop); 404 explicit AutoRunState(MessageLoop* loop);
401 ~AutoRunState(); 405 ~AutoRunState();
402 private: 406 private:
403 MessageLoop* loop_; 407 MessageLoop* loop_;
404 RunState* previous_state_; 408 RunState* previous_state_;
405 }; 409 };
406 #if defined(OS_ANDROID) 410 #if defined(OS_ANDROID)
407 protected: 411 protected:
408 #endif 412 #endif
409 413
410 // This structure is copied around by value.
411 struct PendingTask : public base::TrackingInfo {
412 PendingTask(const base::Closure& task,
413 const tracked_objects::Location& posted_from,
414 base::TimeTicks delayed_run_time,
415 bool nestable);
416 ~PendingTask();
417
418 // Used to support sorting.
419 bool operator<(const PendingTask& other) const;
420
421 // The task to run.
422 base::Closure task;
423
424 // The site this PendingTask was posted from.
425 tracked_objects::Location posted_from;
426
427 // Secondary sort key for run time.
428 int sequence_num;
429
430 // OK to dispatch from a nested loop.
431 bool nestable;
432 };
433
434 class TaskQueue : public std::queue<PendingTask> {
435 public:
436 void Swap(TaskQueue* queue) {
437 c.swap(queue->c); // Calls std::deque::swap
438 }
439 };
440
441 typedef std::priority_queue<PendingTask> DelayedTaskQueue;
442
443 #if defined(OS_WIN) 414 #if defined(OS_WIN)
444 base::MessagePumpWin* pump_win() { 415 base::MessagePumpWin* pump_win() {
445 return static_cast<base::MessagePumpWin*>(pump_.get()); 416 return static_cast<base::MessagePumpWin*>(pump_.get());
446 } 417 }
447 #elif defined(OS_POSIX) 418 #elif defined(OS_POSIX)
448 base::MessagePumpLibevent* pump_libevent() { 419 base::MessagePumpLibevent* pump_libevent() {
449 return static_cast<base::MessagePumpLibevent*>(pump_.get()); 420 return static_cast<base::MessagePumpLibevent*>(pump_.get());
450 } 421 }
451 #endif 422 #endif
452 423
453 // A function to encapsulate all the exception handling capability in the 424 // A function to encapsulate all the exception handling capability in the
454 // stacks around the running of a main message loop. It will run the message 425 // stacks around the running of a main message loop. It will run the message
455 // loop in a SEH try block or not depending on the set_SEH_restoration() 426 // loop in a SEH try block or not depending on the set_SEH_restoration()
456 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). 427 // flag invoking respectively RunInternalInSEHFrame() or RunInternal().
457 void RunHandler(); 428 void RunHandler();
458 429
459 #if defined(OS_WIN) 430 #if defined(OS_WIN)
460 __declspec(noinline) void RunInternalInSEHFrame(); 431 __declspec(noinline) void RunInternalInSEHFrame();
461 #endif 432 #endif
462 433
463 // A surrounding stack frame around the running of the message loop that 434 // A surrounding stack frame around the running of the message loop that
464 // supports all saving and restoring of state, as is needed for any/all (ugly) 435 // supports all saving and restoring of state, as is needed for any/all (ugly)
465 // recursive calls. 436 // recursive calls.
466 void RunInternal(); 437 void RunInternal();
467 438
468 // Called to process any delayed non-nestable tasks. 439 // Called to process any delayed non-nestable tasks.
469 bool ProcessNextDelayedNonNestableTask(); 440 bool ProcessNextDelayedNonNestableTask();
470 441
471 // Runs the specified PendingTask. 442 // Runs the specified PendingTask.
472 void RunTask(const PendingTask& pending_task); 443 void RunTask(const base::PendingTask& pending_task);
473 444
474 // Calls RunTask or queues the pending_task on the deferred task list if it 445 // Calls RunTask or queues the pending_task on the deferred task list if it
475 // cannot be run right now. Returns true if the task was run. 446 // cannot be run right now. Returns true if the task was run.
476 bool DeferOrRunPendingTask(const PendingTask& pending_task); 447 bool DeferOrRunPendingTask(const base::PendingTask& pending_task);
477 448
478 // Adds the pending task to delayed_work_queue_. 449 // Adds the pending task to delayed_work_queue_.
479 void AddToDelayedWorkQueue(const PendingTask& pending_task); 450 void AddToDelayedWorkQueue(const base::PendingTask& pending_task);
480 451
481 // Adds the pending task to our incoming_queue_. 452 // Adds the pending task to our incoming_queue_.
482 // 453 //
483 // Caller retains ownership of |pending_task|, but this function will 454 // Caller retains ownership of |pending_task|, but this function will
484 // reset the value of pending_task->task. This is needed to ensure 455 // reset the value of pending_task->task. This is needed to ensure
485 // that the posting call stack does not retain pending_task->task 456 // that the posting call stack does not retain pending_task->task
486 // beyond this function call. 457 // beyond this function call.
487 void AddToIncomingQueue(PendingTask* pending_task); 458 void AddToIncomingQueue(base::PendingTask* pending_task);
488 459
489 // Load tasks from the incoming_queue_ into work_queue_ if the latter is 460 // Load tasks from the incoming_queue_ into work_queue_ if the latter is
490 // empty. The former requires a lock to access, while the latter is directly 461 // empty. The former requires a lock to access, while the latter is directly
491 // accessible on this thread. 462 // accessible on this thread.
492 void ReloadWorkQueue(); 463 void ReloadWorkQueue();
493 464
494 // Delete tasks that haven't run yet without running them. Used in the 465 // Delete tasks that haven't run yet without running them. Used in the
495 // destructor to make sure all the task's destructors get called. Returns 466 // destructor to make sure all the task's destructors get called. Returns
496 // true if some work was done. 467 // true if some work was done.
497 bool DeletePendingTasks(); 468 bool DeletePendingTasks();
498 469
499 // Calcuates the time at which a PendingTask should run. 470 // Calculates the time at which a PendingTask should run.
500 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms); 471 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms);
501 472
502 // Start recording histogram info about events and action IF it was enabled 473 // Start recording histogram info about events and action IF it was enabled
503 // and IF the statistics recorder can accept a registration of our histogram. 474 // and IF the statistics recorder can accept a registration of our histogram.
504 void StartHistogrammer(); 475 void StartHistogrammer();
505 476
506 // Add occurence of event to our histogram, so that we can see what is being 477 // Add occurrence of event to our histogram, so that we can see what is being
507 // done in a specific MessageLoop instance (i.e., specific thread). 478 // done in a specific MessageLoop instance (i.e., specific thread).
508 // If message_histogram_ is NULL, this is a no-op. 479 // If message_histogram_ is NULL, this is a no-op.
509 void HistogramEvent(int event); 480 void HistogramEvent(int event);
510 481
511 // base::MessagePump::Delegate methods: 482 // base::MessagePump::Delegate methods:
512 virtual bool DoWork(); 483 virtual bool DoWork();
513 virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time); 484 virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time);
514 virtual bool DoIdleWork(); 485 virtual bool DoIdleWork();
515 486
516 Type type_; 487 Type type_;
517 488
518 // A list of tasks that need to be processed by this instance. Note that 489 // A list of tasks that need to be processed by this instance. Note that
519 // this queue is only accessed (push/pop) by our current thread. 490 // this queue is only accessed (push/pop) by our current thread.
520 TaskQueue work_queue_; 491 base::TaskQueue work_queue_;
521 492
522 // Contains delayed tasks, sorted by their 'delayed_run_time' property. 493 // Contains delayed tasks, sorted by their 'delayed_run_time' property.
523 DelayedTaskQueue delayed_work_queue_; 494 DelayedTaskQueue delayed_work_queue_;
524 495
525 // A recent snapshot of Time::Now(), used to check delayed_work_queue_. 496 // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
526 base::TimeTicks recent_time_; 497 base::TimeTicks recent_time_;
527 498
528 // A queue of non-nestable tasks that we had to defer because when it came 499 // A queue of non-nestable tasks that we had to defer because when it came
529 // time to execute them we were in a nested message loop. They will execute 500 // time to execute them we were in a nested message loop. They will execute
530 // once we're out of nested message loops. 501 // once we're out of nested message loops.
531 TaskQueue deferred_non_nestable_work_queue_; 502 base::TaskQueue deferred_non_nestable_work_queue_;
532 503
533 scoped_refptr<base::MessagePump> pump_; 504 scoped_refptr<base::MessagePump> pump_;
534 505
535 ObserverList<DestructionObserver> destruction_observers_; 506 ObserverList<DestructionObserver> destruction_observers_;
536 507
537 // A recursion block that prevents accidentally running additonal tasks when 508 // A recursion block that prevents accidentally running additional tasks when
538 // insider a (accidentally induced?) nested message pump. 509 // insider a (accidentally induced?) nested message pump.
539 bool nestable_tasks_allowed_; 510 bool nestable_tasks_allowed_;
540 511
541 bool exception_restoration_; 512 bool exception_restoration_;
542 513
543 std::string thread_name_; 514 std::string thread_name_;
544 // A profiling histogram showing the counts of various messages and events. 515 // A profiling histogram showing the counts of various messages and events.
545 base::Histogram* message_histogram_; 516 base::Histogram* message_histogram_;
546 517
547 // A null terminated list which creates an incoming_queue of tasks that are 518 // A null terminated list which creates an incoming_queue of tasks that are
548 // acquired under a mutex for processing on this instance's thread. These 519 // acquired under a mutex for processing on this instance's thread. These
549 // tasks have not yet been sorted out into items for our work_queue_ vs items 520 // tasks have not yet been sorted out into items for our work_queue_ vs items
550 // that will be handled by the TimerManager. 521 // that will be handled by the TimerManager.
551 TaskQueue incoming_queue_; 522 base::TaskQueue incoming_queue_;
552 // Protect access to incoming_queue_. 523 // Protect access to incoming_queue_.
553 mutable base::Lock incoming_queue_lock_; 524 mutable base::Lock incoming_queue_lock_;
554 525
555 RunState* state_; 526 RunState* state_;
556 527
557 // The need for this variable is subtle. Please see implementation comments 528 // The need for this variable is subtle. Please see implementation comments
558 // around where it is used. 529 // around where it is used.
559 bool should_leak_tasks_; 530 bool should_leak_tasks_;
560 531
561 #if defined(OS_WIN) 532 #if defined(OS_WIN)
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 #endif // defined(OS_POSIX) 669 #endif // defined(OS_POSIX)
699 }; 670 };
700 671
701 // Do not add any member variables to MessageLoopForIO! This is important b/c 672 // Do not add any member variables to MessageLoopForIO! This is important b/c
702 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra 673 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra
703 // data that you need should be stored on the MessageLoop's pump_ instance. 674 // data that you need should be stored on the MessageLoop's pump_ instance.
704 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), 675 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
705 MessageLoopForIO_should_not_have_extra_member_variables); 676 MessageLoopForIO_should_not_have_extra_member_variables);
706 677
707 #endif // BASE_MESSAGE_LOOP_H_ 678 #endif // BASE_MESSAGE_LOOP_H_
OLDNEW
« no previous file with comments | « base/base.gypi ('k') | base/message_loop.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698