Switch to using TimeTicks rather than Time in message loops

Switch to using TimeTicks rather than Time so that we
are not dependent on changes in the system clock.

r=mbelshe,darin
Review URL: http://codereview.chromium.org/3884001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65322 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/base/message_loop.cc b/base/message_loop.cc
index b860fd8..efbced1b 100644
--- a/base/message_loop.cc
+++ b/base/message_loop.cc
@@ -29,6 +29,7 @@
 
 using base::Time;
 using base::TimeDelta;
+using base::TimeTicks;
 
 namespace {
 
@@ -332,7 +333,7 @@
 
   if (delay_ms > 0) {
     pending_task.delayed_run_time =
-        Time::Now() + TimeDelta::FromMilliseconds(delay_ms);
+        TimeTicks::Now() + TimeDelta::FromMilliseconds(delay_ms);
 
 #if defined(OS_WIN)
     if (high_resolution_timer_expiration_.is_null()) {
@@ -345,7 +346,7 @@
           delay_ms < (2 * Time::kMinLowResolutionThresholdMs);
       if (needs_high_res_timers) {
         Time::ActivateHighResolutionTimer(true);
-        high_resolution_timer_expiration_ = base::TimeTicks::Now() +
+        high_resolution_timer_expiration_ = TimeTicks::Now() +
             TimeDelta::FromMilliseconds(kHighResolutionTimerModeLeaseTimeMs);
       }
     }
@@ -356,9 +357,9 @@
 
 #if defined(OS_WIN)
   if (!high_resolution_timer_expiration_.is_null()) {
-    if (base::TimeTicks::Now() > high_resolution_timer_expiration_) {
+    if (TimeTicks::Now() > high_resolution_timer_expiration_) {
       Time::ActivateHighResolutionTimer(false);
-      high_resolution_timer_expiration_ = base::TimeTicks();
+      high_resolution_timer_expiration_ = TimeTicks();
     }
   }
 #endif
@@ -540,21 +541,22 @@
   return false;
 }
 
-bool MessageLoop::DoDelayedWork(base::Time* next_delayed_work_time) {
+bool MessageLoop::DoDelayedWork(base::TimeTicks* next_delayed_work_time) {
   if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) {
-    recent_time_ = *next_delayed_work_time = base::Time();
+    recent_time_ = *next_delayed_work_time = TimeTicks();
     return false;
   }
 
-  // When we "fall behind," there may be a lot of tasks in the delayed work
+  // When we "fall behind," there will be a lot of tasks in the delayed work
   // queue that are ready to run.  To increase efficiency when we fall behind,
   // we will only call Time::Now() intermittently, and then process all tasks
   // that are ready to run before calling it again.  As a result, the more we
   // fall behind (and have a lot of ready-to-run delayed tasks), the more
   // efficient we'll be at handling the tasks.
-  base::Time next_run_time = delayed_work_queue_.top().delayed_run_time;
+
+  TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time;
   if (next_run_time > recent_time_) {
-    recent_time_ = base::Time::Now();  // Get a better view of Now().
+    recent_time_ = TimeTicks::Now();  // Get a better view of Now();
     if (next_run_time > recent_time_) {
       *next_delayed_work_time = next_run_time;
       return false;
diff --git a/base/message_loop.h b/base/message_loop.h
index 9ac45ab..a5a94bc 100644
--- a/base/message_loop.h
+++ b/base/message_loop.h
@@ -341,10 +341,10 @@
 
   // This structure is copied around by value.
   struct PendingTask {
-    Task* task;                   // The task to run.
-    base::Time delayed_run_time;  // The time when the task should be run.
-    int sequence_num;             // Used to facilitate sorting by run time.
-    bool nestable;                // True if OK to dispatch from a nested loop.
+    Task* task;                        // The task to run.
+    base::TimeTicks delayed_run_time;  // The time when the task should be run.
+    int sequence_num;                  // Secondary sort key for run time.
+    bool nestable;                     // OK to dispatch from a nested loop.
 
     PendingTask(Task* task, bool nestable)
         : task(task), sequence_num(0), nestable(nestable) {
@@ -429,7 +429,7 @@
 
   // base::MessagePump::Delegate methods:
   virtual bool DoWork();
-  virtual bool DoDelayedWork(base::Time* next_delayed_work_time);
+  virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time);
   virtual bool DoIdleWork();
 
   // Start recording histogram info about events and action IF it was enabled
@@ -451,7 +451,7 @@
   DelayedTaskQueue delayed_work_queue_;
 
   // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
-  base::Time recent_time_;
+  base::TimeTicks recent_time_;
 
   // A queue of non-nestable tasks that we had to defer because when it came
   // time to execute them we were in a nested message loop.  They will execute
diff --git a/base/message_pump.h b/base/message_pump.h
index f8a097d..a354724 100644
--- a/base/message_pump.h
+++ b/base/message_pump.h
@@ -10,7 +10,7 @@
 
 namespace base {
 
-class Time;
+class TimeTicks;
 
 class MessagePump : public RefCountedThreadSafe<MessagePump> {
  public:
@@ -33,7 +33,7 @@
     // |next_delayed_work_time| is null (per Time::is_null), then the queue of
     // future delayed work (timer events) is currently empty, and no additional
     // calls to this function need to be scheduled.
-    virtual bool DoDelayedWork(Time* next_delayed_work_time) = 0;
+    virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) = 0;
 
     // Called from within Run just before the message pump goes to sleep.
     // Returns true to indicate that idle work was done.
@@ -116,7 +116,7 @@
   // Schedule a DoDelayedWork callback to happen at the specified time,
   // cancelling any pending DoDelayedWork callback.  This method may only be
   // used on the thread that called Run.
-  virtual void ScheduleDelayedWork(const Time& delayed_work_time) = 0;
+  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) = 0;
 };
 
 }  // namespace base
diff --git a/base/message_pump_default.cc b/base/message_pump_default.cc
index 518684a..d9eddc41 100644
--- a/base/message_pump_default.cc
+++ b/base/message_pump_default.cc
@@ -41,13 +41,13 @@
     if (delayed_work_time_.is_null()) {
       event_.Wait();
     } else {
-      TimeDelta delay = delayed_work_time_ - Time::Now();
+      TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
       if (delay > TimeDelta()) {
         event_.TimedWait(delay);
       } else {
         // It looks like delayed_work_time_ indicates a time in the past, so we
         // need to call DoDelayedWork now.
-        delayed_work_time_ = Time();
+        delayed_work_time_ = TimeTicks();
       }
     }
     // Since event_ is auto-reset, we don't need to do anything special here
@@ -67,7 +67,8 @@
   event_.Signal();
 }
 
-void MessagePumpDefault::ScheduleDelayedWork(const Time& delayed_work_time) {
+void MessagePumpDefault::ScheduleDelayedWork(
+    const TimeTicks& delayed_work_time) {
   // We know that we can't be blocked on Wait right now since this method can
   // only be called on the same thread as Run, so we only need to update our
   // record of how long to sleep when we do sleep.
diff --git a/base/message_pump_default.h b/base/message_pump_default.h
index 0ac6cd4d..3dfbf1c 100644
--- a/base/message_pump_default.h
+++ b/base/message_pump_default.h
@@ -21,7 +21,7 @@
   virtual void Run(Delegate* delegate);
   virtual void Quit();
   virtual void ScheduleWork();
-  virtual void ScheduleDelayedWork(const Time& delayed_work_time);
+  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
 
  private:
   // This flag is set to false when Run should return.
@@ -31,7 +31,7 @@
   WaitableEvent event_;
 
   // The time at which we should call DoDelayedWork.
-  Time delayed_work_time_;
+  TimeTicks delayed_work_time_;
 
   DISALLOW_COPY_AND_ASSIGN(MessagePumpDefault);
 };
diff --git a/base/message_pump_glib.cc b/base/message_pump_glib.cc
index 616c24cb..fa5b726 100644
--- a/base/message_pump_glib.cc
+++ b/base/message_pump_glib.cc
@@ -21,7 +21,7 @@
 
 // Return a timeout suitable for the glib loop, -1 to block forever,
 // 0 to return right away, or a timeout in milliseconds from now.
-int GetTimeIntervalMilliseconds(base::Time from) {
+int GetTimeIntervalMilliseconds(const base::TimeTicks& from) {
   if (from.is_null())
     return -1;
 
@@ -29,7 +29,7 @@
   // value in milliseconds.  If there are 5.5ms left, should the delay be 5 or
   // 6?  It should be 6 to avoid executing delayed work too early.
   int delay = static_cast<int>(
-      ceil((from - base::Time::Now()).InMillisecondsF()));
+      ceil((from - base::TimeTicks::Now()).InMillisecondsF()));
 
   // If this value is negative, then we need to run delayed work soon.
   return delay < 0 ? 0 : delay;
@@ -333,7 +333,7 @@
   }
 }
 
-void MessagePumpForUI::ScheduleDelayedWork(const Time& delayed_work_time) {
+void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
   // We need to wake up the loop in case the poll timeout needs to be
   // adjusted.  This will cause us to try to do work, but that's ok.
   delayed_work_time_ = delayed_work_time;
diff --git a/base/message_pump_glib.h b/base/message_pump_glib.h
index d8cbbda..06635de 100644
--- a/base/message_pump_glib.h
+++ b/base/message_pump_glib.h
@@ -65,7 +65,7 @@
   virtual void Run(Delegate* delegate) { RunWithDispatcher(delegate, NULL); }
   virtual void Quit();
   virtual void ScheduleWork();
-  virtual void ScheduleDelayedWork(const Time& delayed_work_time);
+  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
 
   // Internal methods used for processing the pump callbacks.  They are
   // public for simplicity but should not be used directly.  HandlePrepare
@@ -116,7 +116,7 @@
   GMainContext* context_;
 
   // This is the time when we need to do delayed work.
-  Time delayed_work_time_;
+  TimeTicks delayed_work_time_;
 
   // The work source.  It is shared by all calls to Run and destroyed when
   // the message pump is destroyed.
diff --git a/base/message_pump_libevent.cc b/base/message_pump_libevent.cc
index d325957..1410f79 100644
--- a/base/message_pump_libevent.cc
+++ b/base/message_pump_libevent.cc
@@ -290,7 +290,7 @@
     if (delayed_work_time_.is_null()) {
       event_base_loop(event_base_, EVLOOP_ONCE);
     } else {
-      TimeDelta delay = delayed_work_time_ - Time::Now();
+      TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
       if (delay > TimeDelta()) {
         struct timeval poll_tv;
         poll_tv.tv_sec = delay.InSeconds();
@@ -303,7 +303,7 @@
       } else {
         // It looks like delayed_work_time_ indicates a time in the past, so we
         // need to call DoDelayedWork now.
-        delayed_work_time_ = Time();
+        delayed_work_time_ = TimeTicks();
       }
     }
   }
@@ -326,7 +326,8 @@
       << "[nwrite:" << nwrite << "] [errno:" << errno << "]";
 }
 
-void MessagePumpLibevent::ScheduleDelayedWork(const Time& delayed_work_time) {
+void MessagePumpLibevent::ScheduleDelayedWork(
+    const TimeTicks& delayed_work_time) {
   // We know that we can't be blocked on Wait right now since this method can
   // only be called on the same thread as Run, so we only need to update our
   // record of how long to sleep when we do sleep.
diff --git a/base/message_pump_libevent.h b/base/message_pump_libevent.h
index f271612..d8d000d1 100644
--- a/base/message_pump_libevent.h
+++ b/base/message_pump_libevent.h
@@ -119,7 +119,7 @@
   virtual void Run(Delegate* delegate);
   virtual void Quit();
   virtual void ScheduleWork();
-  virtual void ScheduleDelayedWork(const Time& delayed_work_time);
+  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
 
  private:
   void WillProcessIOEvent();
@@ -135,7 +135,7 @@
   bool in_run_;
 
   // The time at which we should call DoDelayedWork.
-  Time delayed_work_time_;
+  TimeTicks delayed_work_time_;
 
   // Libevent dispatcher.  Watches all sockets registered with it, and sends
   // readiness callbacks when a socket is ready for I/O.
diff --git a/base/message_pump_mac.h b/base/message_pump_mac.h
index 59a7329..e016d54 100644
--- a/base/message_pump_mac.h
+++ b/base/message_pump_mac.h
@@ -44,7 +44,7 @@
 
 namespace base {
 
-class Time;
+class TimeTicks;
 
 class MessagePumpCFRunLoopBase : public MessagePump {
   // Needs access to CreateAutoreleasePool.
@@ -61,7 +61,7 @@
   virtual void DoRun(Delegate* delegate) = 0;
 
   virtual void ScheduleWork();
-  virtual void ScheduleDelayedWork(const Time& delayed_work_time);
+  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
 
  protected:
   // Accessors for private data members to be used by subclasses.
diff --git a/base/message_pump_mac.mm b/base/message_pump_mac.mm
index 16a9a599..9091006 100644
--- a/base/message_pump_mac.mm
+++ b/base/message_pump_mac.mm
@@ -225,11 +225,17 @@
 
 // Must be called on the run loop thread.
 void MessagePumpCFRunLoopBase::ScheduleDelayedWork(
-    const Time& delayed_work_time) {
+    const TimeTicks& delayed_work_time) {
+  // TODO(jar): We may need a more efficient way to go between these times, but
+  // the difference will change not only when we sleep/wake, it will also change
+  // when the user changes the wall clock time :-/.
+  Time absolute_work_time =
+      (delayed_work_time - TimeTicks::Now()) + Time::Now();
+
   Time::Exploded exploded;
-  delayed_work_time.UTCExplode(&exploded);
+  absolute_work_time.UTCExplode(&exploded);
   double seconds = exploded.second +
-                   (static_cast<double>((delayed_work_time.ToInternalValue()) %
+                   (static_cast<double>((absolute_work_time.ToInternalValue()) %
                                         Time::kMicrosecondsPerSecond) /
                     Time::kMicrosecondsPerSecond);
   CFGregorianDate gregorian = {
@@ -320,12 +326,12 @@
   // released promptly even in the absence of UI events.
   MessagePumpScopedAutoreleasePool autorelease_pool(this);
 
-  Time next_time;
+  TimeTicks next_time;
   delegate_->DoDelayedWork(&next_time);
 
   bool more_work = !next_time.is_null();
   if (more_work) {
-    TimeDelta delay = next_time - Time::Now();
+    TimeDelta delay = next_time - TimeTicks::Now();
     if (delay > TimeDelta()) {
       // There's more delayed work to be done in the future.
       ScheduleDelayedWork(next_time);
diff --git a/base/message_pump_win.cc b/base/message_pump_win.cc
index d0afd511..0df888a3 100644
--- a/base/message_pump_win.cc
+++ b/base/message_pump_win.cc
@@ -66,7 +66,8 @@
   // Be careful here.  TimeDelta has a precision of microseconds, but we want a
   // value in milliseconds.  If there are 5.5ms left, should the delay be 5 or
   // 6?  It should be 6 to avoid executing delayed work too early.
-  double timeout = ceil((delayed_work_time_ - Time::Now()).InMillisecondsF());
+  double timeout =
+      ceil((delayed_work_time_ - TimeTicks::Now()).InMillisecondsF());
 
   // If this value is negative, then we need to run delayed work soon.
   int delay = static_cast<int>(timeout);
@@ -96,7 +97,7 @@
   PostMessage(message_hwnd_, kMsgHaveWork, reinterpret_cast<WPARAM>(this), 0);
 }
 
-void MessagePumpForUI::ScheduleDelayedWork(const Time& delayed_work_time) {
+void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
   //
   // We would *like* to provide high resolution timers.  Windows timers using
   // SetTimer() have a 10ms granularity.  We have to use WM_TIMER as a wakeup
@@ -409,7 +410,7 @@
   DCHECK(ret);
 }
 
-void MessagePumpForIO::ScheduleDelayedWork(const Time& delayed_work_time) {
+void MessagePumpForIO::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
   // We know that we can't be blocked right now since this method can only be
   // called on the same thread as Run, so we only need to update our record of
   // how long to sleep when we do sleep.
diff --git a/base/message_pump_win.h b/base/message_pump_win.h
index d7d53cb..d57fe1d 100644
--- a/base/message_pump_win.h
+++ b/base/message_pump_win.h
@@ -98,7 +98,7 @@
   ObserverList<Observer> observers_;
 
   // The time at which delayed work should run.
-  Time delayed_work_time_;
+  TimeTicks delayed_work_time_;
 
   // A boolean value used to indicate if there is a kMsgDoWork message pending
   // in the Windows Message queue.  There is at most one such message, and it
@@ -167,7 +167,7 @@
 
   // MessagePump methods:
   virtual void ScheduleWork();
-  virtual void ScheduleDelayedWork(const Time& delayed_work_time);
+  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
 
   // Applications can call this to encourage us to process all pending WM_PAINT
   // messages.  This method will process all paint messages the Windows Message
@@ -319,7 +319,7 @@
 
   // MessagePump methods:
   virtual void ScheduleWork();
-  virtual void ScheduleDelayedWork(const Time& delayed_work_time);
+  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
 
   // Register the handler to be used when asynchronous IO for the given file
   // completes. The registration persists as long as |file_handle| is valid, so
diff --git a/remoting/jingle_glue/jingle_thread.cc b/remoting/jingle_glue/jingle_thread.cc
index e4ab098..25f646a 100644
--- a/remoting/jingle_glue/jingle_thread.cc
+++ b/remoting/jingle_glue/jingle_thread.cc
@@ -25,7 +25,7 @@
   virtual void ScheduleWork() {
     thread_->Post(this, kRunTasksMessageId);
   }
-  virtual void ScheduleDelayedWork(const base::Time& time) {
+  virtual void ScheduleDelayedWork(const base::TimeTicks& time) {
     delayed_work_time_ = time;
     ScheduleNextDelayedTask();
   }
@@ -66,7 +66,7 @@
     DCHECK_EQ(thread_->message_loop(), MessageLoop::current());
 
     if (!delayed_work_time_.is_null()) {
-      base::Time now = base::Time::Now();
+      base::TimeTicks now = base::TimeTicks::Now();
       int delay = static_cast<int>((delayed_work_time_ - now).InMilliseconds());
       if (delay > 0) {
         thread_->PostDelayed(delay, this, kRunTasksMessageId);
@@ -77,7 +77,7 @@
   }
 
   JingleThread* thread_;
-  base::Time delayed_work_time_;
+  base::TimeTicks delayed_work_time_;
 };
 
 class JingleThread::JingleMessageLoop : public MessageLoop {