Revert 212948 "Made MessagePump a non-thread safe class."

r212948 broke Mac Builder: http://build.chromium.org/p/chromium.memory/builders/Mac%20ASAN%20Builder/builds/25623

> Made MessagePump a non-thread safe class.
> 
> This CL makes MessagePump a non-thread safe class to make sure thread-bound resources (such as the UI window used for pumping messages on Windows) are freed on the correct thread.
> 
> Handling of incoming tasks and synchronization between different threads was moved out to a separate class - IncomingTaskQueue reducing the number of locks to be taken while posting a task to one. Posting tasks via both MessageLoop and MessageLoopProxyImpl is now routed via IncomingTaskQueue.
> 
> BUG=241939
> 
> Review URL: https://chromiumcodereview.appspot.com/17567007

TBR=alexeypa@chromium.org

Review URL: https://codereview.chromium.org/19737005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212952 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: c9904b429860b83606492d4fe8f1b232c04753b5
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index 6f71a85..846cc8d 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -13,10 +13,7 @@
 #include "base/callback_forward.h"
 #include "base/location.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/incoming_task_queue.h"
 #include "base/message_loop/message_loop_proxy.h"
-#include "base/message_loop/message_loop_proxy_impl.h"
 #include "base/message_loop/message_pump.h"
 #include "base/observer_list.h"
 #include "base/pending_task.h"
@@ -49,12 +46,12 @@
 namespace base {
 
 class HistogramBase;
+class MessageLoopLockTest;
 class RunLoop;
 class ThreadTaskRunnerHandle;
 #if defined(OS_ANDROID)
 class MessagePumpForUI;
 #endif
-class WaitableEvent;
 
 // A MessageLoop is used to process events for a particular thread.  There is
 // at most one MessageLoop instance per thread.
@@ -286,7 +283,7 @@
 
   // Gets the message loop proxy associated with this message loop.
   scoped_refptr<MessageLoopProxy> message_loop_proxy() {
-    return message_loop_proxy_;
+    return message_loop_proxy_.get();
   }
 
   // Enables or disables the recursive task processing. This happens in the case
@@ -362,10 +359,23 @@
   void AddTaskObserver(TaskObserver* task_observer);
   void RemoveTaskObserver(TaskObserver* task_observer);
 
+  // Returns true if the message loop has high resolution timers enabled.
+  // Provided for testing.
+  bool high_resolution_timers_enabled() {
+#if defined(OS_WIN)
+    return !high_resolution_timer_expiration_.is_null();
+#else
+    return true;
+#endif
+  }
+
   // When we go into high resolution timer mode, we will stay in hi-res mode
   // for at least 1s.
   static const int kHighResolutionTimerModeLeaseTimeMs = 1000;
 
+  // Asserts that the MessageLoop is "idle".
+  void AssertIdle() const;
+
 #if defined(OS_WIN)
   void set_os_modal_loop(bool os_modal_loop) {
     os_modal_loop_ = os_modal_loop;
@@ -379,18 +389,6 @@
   // Can only be called from the thread that owns the MessageLoop.
   bool is_running() const;
 
-  // Returns true if the message loop has high resolution timers enabled.
-  // Provided for testing.
-  bool IsHighResolutionTimerEnabledForTesting();
-
-  // Returns true if the message loop is "idle". Provided for testing.
-  bool IsIdleForTesting();
-
-  // Takes the incoming queue lock, signals |caller_wait| and waits until
-  // |caller_signal| is signalled.
-  void LockWaitUnLockForTesting(WaitableEvent* caller_wait,
-                                WaitableEvent* caller_signal);
-
   //----------------------------------------------------------------------------
  protected:
 
@@ -404,11 +402,11 @@
   }
 #endif
 
-  scoped_ptr<MessagePump> pump_;
+  scoped_refptr<MessagePump> pump_;
 
  private:
-  friend class internal::IncomingTaskQueue;
   friend class RunLoop;
+  friend class MessageLoopLockTest;
 
   // A function to encapsulate all the exception handling capability in the
   // stacks around the running of a main message loop.  It will run the message
@@ -438,23 +436,34 @@
   // Adds the pending task to delayed_work_queue_.
   void AddToDelayedWorkQueue(const PendingTask& pending_task);
 
+  // This function attempts to add pending task to our incoming_queue_.
+  // The append can only possibly fail when |use_try_lock| is true.
+  //
+  // When |use_try_lock| is true, then this call will avoid blocking if
+  // the related lock is already held, and will in that case (when the
+  // lock is contended) fail to perform the append, and will return false.
+  //
+  // If the call succeeds to append to the queue, then this call
+  // will return true.
+  //
+  // In all cases, the caller retains ownership of |pending_task|, but this
+  // function will reset the value of pending_task->task.  This is needed to
+  // ensure that the posting call stack does not retain pending_task->task
+  // beyond this function call.
+  bool AddToIncomingQueue(PendingTask* pending_task, bool use_try_lock);
+
+  // Load tasks from the incoming_queue_ into work_queue_ if the latter is
+  // empty.  The former requires a lock to access, while the latter is directly
+  // accessible on this thread.
+  void ReloadWorkQueue();
+
   // Delete tasks that haven't run yet without running them.  Used in the
   // destructor to make sure all the task's destructors get called.  Returns
   // true if some work was done.
   bool DeletePendingTasks();
 
-  // Creates a process-wide unique ID to represent this task in trace events.
-  // This will be mangled with a Process ID hash to reduce the likelyhood of
-  // colliding with MessageLoop pointers on other processes.
-  uint64 GetTaskTraceID(const PendingTask& task);
-
-  // Loads tasks from the incoming queue to |work_queue_| if the latter is
-  // empty.
-  void ReloadWorkQueue();
-
-  // Wakes up the message pump. Can be called on any thread. The caller is
-  // responsible for synchronizing ScheduleWork() calls.
-  void ScheduleWork(bool was_empty);
+  // Calculates the time at which a PendingTask should run.
+  TimeTicks CalculateDelayedRuntime(TimeDelta delay);
 
   // Start recording histogram info about events and action IF it was enabled
   // and IF the statistics recorder can accept a registration of our histogram.
@@ -489,30 +498,40 @@
 
   ObserverList<DestructionObserver> destruction_observers_;
 
-  bool exception_restoration_;
-
   // A recursion block that prevents accidentally running additional tasks when
   // insider a (accidentally induced?) nested message pump.
   bool nestable_tasks_allowed_;
 
-#if defined(OS_WIN)
-  // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
-  // which enter a modal message loop.
-  bool os_modal_loop_;
-#endif
+  bool exception_restoration_;
 
   std::string thread_name_;
   // A profiling histogram showing the counts of various messages and events.
   HistogramBase* message_histogram_;
 
+  // An incoming queue of tasks that are acquired under a mutex for processing
+  // on this instance's thread. These tasks have not yet been sorted out into
+  // items for our work_queue_ vs delayed_work_queue_.
+  TaskQueue incoming_queue_;
+  // Protect access to incoming_queue_.
+  mutable Lock incoming_queue_lock_;
+
   RunLoop* run_loop_;
 
+#if defined(OS_WIN)
+  TimeTicks high_resolution_timer_expiration_;
+  // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
+  // which enter a modal message loop.
+  bool os_modal_loop_;
+#endif
+
+  // The next sequence number to use for delayed tasks. Updating this counter is
+  // protected by incoming_queue_lock_.
+  int next_sequence_num_;
+
   ObserverList<TaskObserver> task_observers_;
 
-  scoped_refptr<internal::IncomingTaskQueue> incoming_task_queue_;
-
-  // The message loop proxy associated with this message loop.
-  scoped_refptr<internal::MessageLoopProxyImpl> message_loop_proxy_;
+  // The message loop proxy associated with this message loop, if one exists.
+  scoped_refptr<MessageLoopProxy> message_loop_proxy_;
   scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
 
   template <class T, class R> friend class base::subtle::DeleteHelperInternal;