diff options
| author | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-20 01:13:40 +0000 | 
|---|---|---|
| committer | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-20 01:13:40 +0000 | 
| commit | 3816f46725f7b8e42e352a063efd5206a46dbe9a (patch) | |
| tree | d64edfcf741dcd927ce404f66dab723e8a0914c8 | |
| parent | bda05798c0609582075a3b872c37ad56021920c4 (diff) | |
| download | chromium_src-3816f46725f7b8e42e352a063efd5206a46dbe9a.zip chromium_src-3816f46725f7b8e42e352a063efd5206a46dbe9a.tar.gz chromium_src-3816f46725f7b8e42e352a063efd5206a46dbe9a.tar.bz2 | |
rollback r1075 to see if it helps resolve test failures
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1078 0039d316-1c4b-4281-b951-d872f2087c98
| -rw-r--r-- | base/message_loop.cc | 12 | ||||
| -rw-r--r-- | base/message_loop.h | 2 | ||||
| -rw-r--r-- | base/message_pump.h | 17 | ||||
| -rw-r--r-- | base/message_pump_default.cc | 30 | ||||
| -rw-r--r-- | base/message_pump_default.h | 5 | ||||
| -rw-r--r-- | base/message_pump_win.cc | 37 | ||||
| -rw-r--r-- | base/message_pump_win.h | 2 | ||||
| -rw-r--r-- | base/timer.cc | 20 | ||||
| -rw-r--r-- | base/timer.h | 10 | ||||
| -rw-r--r-- | base/waitable_event_win.cc | 9 | 
10 files changed, 63 insertions, 81 deletions
| diff --git a/base/message_loop.cc b/base/message_loop.cc index eb10ca7..4964dfe 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -386,16 +386,16 @@ void MessageLoop::DeletePendingTasks() {  }  void MessageLoop::DidChangeNextTimerExpiry() { -  Time next_delayed_work_time = timer_manager_.GetNextFireTime();  -  if (next_delayed_work_time.is_null()) +  int delay = timer_manager_.GetCurrentDelay();  +  if (delay == -1)      return;    // Simulates malfunctioning, early firing timers. Pending tasks should only    // be invoked when the delay they specify has elapsed.    if (timer_manager_.use_broken_delay()) -    next_delayed_work_time = Time::Now() + TimeDelta::FromMilliseconds(10); +    delay = 10; -  pump_->ScheduleDelayedWork(next_delayed_work_time); +  pump_->ScheduleDelayedWork(TimeDelta::FromMilliseconds(delay));  }  bool MessageLoop::DoWork() { @@ -403,12 +403,12 @@ bool MessageLoop::DoWork() {    return QueueOrRunTask(NULL);  } -bool MessageLoop::DoDelayedWork(Time* next_delayed_work_time) { +bool MessageLoop::DoDelayedWork(TimeDelta* next_delay) {    bool did_work = timer_manager_.RunSomePendingTimers();    // We may not have run any timers, but we may still have future timers to    // run, so we need to inform the pump again of pending timers. -  *next_delayed_work_time = timer_manager_.GetNextFireTime(); +  *next_delay = TimeDelta::FromMilliseconds(timer_manager_.GetCurrentDelay());    return did_work;  } diff --git a/base/message_loop.h b/base/message_loop.h index 3821519..afcab64 100644 --- a/base/message_loop.h +++ b/base/message_loop.h @@ -415,7 +415,7 @@ class MessageLoop : public base::MessagePump::Delegate {    // base::MessagePump::Delegate methods:    virtual bool DoWork(); -  virtual bool DoDelayedWork(Time* next_delayed_work_time); +  virtual bool DoDelayedWork(TimeDelta* next_delay);    virtual bool DoIdleWork();    // Start recording histogram info about events and action IF it was enabled diff --git a/base/message_pump.h b/base/message_pump.h index 06cef43..a06a435 100644 --- a/base/message_pump.h +++ b/base/message_pump.h @@ -32,7 +32,7 @@  #include "base/ref_counted.h" -class Time; +class TimeDelta;  namespace base { @@ -52,12 +52,11 @@ class MessagePump : public RefCountedThreadSafe<MessagePump> {      // Called from within Run in response to ScheduleDelayedWork or when the      // message pump would otherwise sleep waiting for more work.  Returns true      // to indicate that delayed work was done.  DoIdleWork will not be called -    // if DoDelayedWork returns true.  Upon return |next_delayed_work_time| -    // indicates the time when DoDelayedWork should be called again.  If -    // |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; +    // if DoDelayedWork returns true.  Upon return |next_delay| indicates the +    // next delayed work interval.  If |next_delay| is negative, 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(TimeDelta* next_delay) = 0;      // Called from within Run just before the message pump goes to sleep.      // Returns true to indicate that idle work was done. @@ -138,10 +137,10 @@ class MessagePump : public RefCountedThreadSafe<MessagePump> {    // until it returns a value of false.    virtual void ScheduleWork() = 0; -  // Schedule a DoDelayedWork callback to happen at the specified time, +  // Schedule a DoDelayedWork callback to happen after the specified delay,    // 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 TimeDelta& delay) = 0;  };  }  // namespace base diff --git a/base/message_pump_default.cc b/base/message_pump_default.cc index a45f480..916d035 100644 --- a/base/message_pump_default.cc +++ b/base/message_pump_default.cc @@ -51,13 +51,9 @@ void MessagePumpDefault::Run(Delegate* delegate) {      // TODO(darin): Delayed work will be starved if DoWork continues to return      // true.  We should devise a better strategy. -    // -    // It is tempting to call DoWork followed by DoDelayedWork before checking -    // did_work, but we need to make sure that any tasks that were dispatched -    // prior to a timer actually run before the timer.  Getting that right may -    // require some additional changes. -    did_work = delegate->DoDelayedWork(&delayed_work_time_); +    TimeDelta delay; +    did_work = delegate->DoDelayedWork(&delay);      if (!keep_running_)        break;      if (did_work) @@ -68,18 +64,13 @@ void MessagePumpDefault::Run(Delegate* delegate) {        break;      if (did_work)        continue; +    // When DoIdleWork does not work, we also assume that it ran very quickly +    // such that |delay| still properly indicates how long we are to sleep. -    if (delayed_work_time_.is_null()) { +    if (delay < TimeDelta::FromMilliseconds(0)) {        event_.Wait();      } else { -      TimeDelta delay = delayed_work_time_ - Time::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(); -      } +      event_.TimedWait(delay);      }      // Since event_ is auto-reset, we don't need to do anything special here      // other than service each delegate method. @@ -98,11 +89,12 @@ void MessagePumpDefault::ScheduleWork() {    event_.Signal();  } -void MessagePumpDefault::ScheduleDelayedWork(const Time& delayed_work_time) { +void MessagePumpDefault::ScheduleDelayedWork(const TimeDelta& delay) {    // 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. -  delayed_work_time_ = delayed_work_time; +  // only be called on the same thread as Run, but to ensure that when we do +  // sleep, we sleep for the right time, we signal the event to cause the Run +  // loop to do one more iteration. +  event_.Signal();  }  }  // namespace base diff --git a/base/message_pump_default.h b/base/message_pump_default.h index 7c65013..1c1af71 100644 --- a/base/message_pump_default.h +++ b/base/message_pump_default.h @@ -44,7 +44,7 @@ class MessagePumpDefault : public MessagePump {    virtual void Run(Delegate* delegate);    virtual void Quit();    virtual void ScheduleWork(); -  virtual void ScheduleDelayedWork(const Time& delayed_work_time); +  virtual void ScheduleDelayedWork(const TimeDelta& delay);   private:    // This flag is set to false when Run should return. @@ -53,9 +53,6 @@ class MessagePumpDefault : public MessagePump {    // Used to sleep until there is more work to do.    WaitableEvent event_; -  // The time at which we should call DoDelayedWork. -  Time delayed_work_time_; -    DISALLOW_COPY_AND_ASSIGN(MessagePumpDefault);  }; diff --git a/base/message_pump_win.cc b/base/message_pump_win.cc index 28191ea..f290e44 100644 --- a/base/message_pump_win.cc +++ b/base/message_pump_win.cc @@ -29,8 +29,6 @@  #include "base/message_pump_win.h" -#include <math.h> -  #include "base/histogram.h"  #include "base/win_util.h" @@ -162,7 +160,7 @@ void MessagePumpWin::ScheduleWork() {    PostMessage(message_hwnd_, kMsgHaveWork, reinterpret_cast<WPARAM>(this), 0);  } -void MessagePumpWin::ScheduleDelayedWork(const Time& delayed_work_time) { +void MessagePumpWin::ScheduleDelayedWork(const TimeDelta& delay) {    //    // 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 @@ -183,9 +181,7 @@ void MessagePumpWin::ScheduleDelayedWork(const Time& delayed_work_time) {    // Getting a spurrious SetTimer event firing is benign, as we'll just be    // processing an empty timer queue.    // -  delayed_work_time_ = delayed_work_time; - -  int delay_msec = GetCurrentDelay(); +  int delay_msec = static_cast<int>(delay.InMilliseconds());    DCHECK(delay_msec >= 0);    if (delay_msec < USER_TIMER_MINIMUM)      delay_msec = USER_TIMER_MINIMUM; @@ -254,11 +250,10 @@ void MessagePumpWin::HandleTimerMessage() {    if (!state_)      return; -  state_->delegate->DoDelayedWork(&delayed_work_time_); -  if (!delayed_work_time_.is_null()) { -    // A bit gratuitous to set delayed_work_time_ again, but oh well. -    ScheduleDelayedWork(delayed_work_time_); -  } +  TimeDelta next_delay; +  state_->delegate->DoDelayedWork(&next_delay); +  if (next_delay >= TimeDelta::FromMilliseconds(0)) +    ScheduleDelayedWork(next_delay);  }  void MessagePumpWin::DoRunLoop() { @@ -300,13 +295,14 @@ void MessagePumpWin::DoRunLoop() {      if (more_work_is_plausible)        continue; -    more_work_is_plausible = -        state_->delegate->DoDelayedWork(&delayed_work_time_); +    TimeDelta next_delay; +    more_work_is_plausible = state_->delegate->DoDelayedWork(&next_delay);      // If we did not process any delayed work, then we can assume that our      // existing WM_TIMER if any will fire when delayed work should run.  We      // don't want to disturb that timer if it is already in flight.  However,      // if we did do all remaining delayed work, then lets kill the WM_TIMER. -    if (more_work_is_plausible && delayed_work_time_.is_null()) +    if (more_work_is_plausible && +        next_delay < TimeDelta::FromMilliseconds(0))        KillTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this));      if (state_->should_quit)        break; @@ -523,17 +519,8 @@ int MessagePumpWin::GetCurrentDelay() const {    if (delayed_work_time_.is_null())      return -1; -  // 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((Time::Now() - delayed_work_time_).InMillisecondsF()); - -  // If this value is negative, then we need to run delayed work soon. -  int delay = static_cast<int>(timeout); -  if (delay < 0) -    delay = 0; - -  return delay; +  // This could be a negative value, but that's OK. +  return static_cast<int>((Time::Now() - delayed_work_time_).InMilliseconds());  }  }  // namespace base diff --git a/base/message_pump_win.h b/base/message_pump_win.h index ff021e3..6699fde 100644 --- a/base/message_pump_win.h +++ b/base/message_pump_win.h @@ -161,7 +161,7 @@ class MessagePumpWin : public MessagePump {    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 TimeDelta& delay);   private:    struct RunState { diff --git a/base/timer.cc b/base/timer.cc index aced8cb..46fae6e 100644 --- a/base/timer.cc +++ b/base/timer.cc @@ -55,6 +55,14 @@ Timer::Timer(int delay, Task* task, bool repeating)    Reset();  } +int Timer::GetCurrentDelay() const { +  // Be careful here.  Timers have a precision of microseconds, but this API is +  // in milliseconds.  If there are 5.5ms left, should the delay be 5 or 6?  It +  // should be 6 to avoid timers firing early. +  double delay = ceil((fire_time_ - Time::Now()).InMillisecondsF()); +  return static_cast<int>(delay); +} +  void Timer::Reset() {    creation_time_ = Time::Now();    fire_time_ = creation_time_ + TimeDelta::FromMilliseconds(delay_); @@ -155,7 +163,7 @@ bool TimerManager::RunSomePendingTimers() {    // timers have been set.    const int kMaxTimersPerCall = 2;    for (int i = 0; i < kMaxTimersPerCall; ++i) { -    if (timers_.empty() || timers_.top()->fire_time() > Time::Now()) +    if (timers_.empty() || GetCurrentDelay() > 0)        break;      // Get a pending timer.  Deal with updating the timers_ queue and setting @@ -203,11 +211,13 @@ void TimerManager::StartTimer(Timer* timer) {      DidChangeNextTimer();  } -Time TimerManager::GetNextFireTime() const { +int TimerManager::GetCurrentDelay() {    if (timers_.empty()) -    return Time(); - -  return timers_.top()->fire_time(); +    return -1; +  int delay = timers_.top()->GetCurrentDelay(); +  if (delay < 0) +    delay = 0; +  return delay;  }  void TimerManager::DidChangeNextTimer() { diff --git a/base/timer.h b/base/timer.h index 74fe27b..c23f725 100644 --- a/base/timer.h +++ b/base/timer.h @@ -59,6 +59,9 @@ class Timer {    Task* task() const { return task_; }    void set_task(Task* task) { task_ = task; } +  // Returns the time in msec relative to now that the timer should fire. +  int GetCurrentDelay() const; +    // Returns the absolute time at which the timer should fire.    const Time &fire_time() const { return fire_time_; } @@ -174,10 +177,9 @@ class TimerManager {    // Returns true if it runs a task, false otherwise.    bool RunSomePendingTimers(); -  // The absolute time at which the next timer is to fire.  If there is not a -  // next timer to run, then the is_null property of the returned Time object -  // will be true.  NOTE: This could be a time in the past! -  Time GetNextFireTime() const; +  // The number of milliseconds remaining until the pending timer (top of the +  // pqueue) needs to be fired. Returns -1 if no timers are pending. +  int GetCurrentDelay();  #ifdef UNIT_TEST    // For testing only, used to simulate broken early-firing WM_TIMER diff --git a/base/waitable_event_win.cc b/base/waitable_event_win.cc index e23eea0..da2d2d8 100644 --- a/base/waitable_event_win.cc +++ b/base/waitable_event_win.cc @@ -29,7 +29,6 @@  #include "base/waitable_event.h" -#include <math.h>  #include <windows.h>  #include "base/logging.h" @@ -69,12 +68,8 @@ bool WaitableEvent::Wait() {  }  bool WaitableEvent::TimedWait(const TimeDelta& max_time) { -  DCHECK(max_time >= TimeDelta::FromMicroseconds(0)); -  // Be careful here.  TimeDelta has a precision of microseconds, but this API -  // is in milliseconds.  If there are 5.5ms left, should the delay be 5 or 6? -  // It should be 6 to avoid returning too early. -  double timeout = ceil(max_time.InMillisecondsF()); -  DWORD result = WaitForSingleObject(event_, static_cast<DWORD>(timeout)); +  int32 timeout = static_cast<int32>(max_time.InMilliseconds()); +  DWORD result = WaitForSingleObject(event_, timeout);    switch (result) {      case WAIT_OBJECT_0:        return true; | 
