| Index: base/message_loop/message_pump_win.cc
|
| diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
|
| index 27b47e1a0f878cfceef3c04b2364116ca64ac4c8..226747e5ab855bd64c8ea36b01f9cdb905e3c7dd 100644
|
| --- a/base/message_loop/message_pump_win.cc
|
| +++ b/base/message_loop/message_pump_win.cc
|
| @@ -122,44 +122,8 @@ void MessagePumpForUI::ScheduleWork() {
|
| }
|
|
|
| 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
|
| - // mechanism because the application can enter modal windows loops where it
|
| - // is not running our MessageLoop; the only way to have our timers fire in
|
| - // these cases is to post messages there.
|
| - //
|
| - // To provide sub-10ms timers, we process timers directly from our run loop.
|
| - // For the common case, timers will be processed there as the run loop does
|
| - // its normal work. However, we *also* set the system timer so that WM_TIMER
|
| - // events fire. This mops up the case of timers not being able to work in
|
| - // modal message loops. It is possible for the SetTimer to pop and have no
|
| - // pending timers, because they could have already been processed by the
|
| - // run loop itself.
|
| - //
|
| - // We use a single SetTimer corresponding to the timer that will expire
|
| - // soonest. As new timers are created and destroyed, we update SetTimer.
|
| - // 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();
|
| - DCHECK_GE(delay_msec, 0);
|
| - if (delay_msec < USER_TIMER_MINIMUM)
|
| - delay_msec = USER_TIMER_MINIMUM;
|
| -
|
| - // Create a WM_TIMER event that will wake us up to check for any pending
|
| - // timers (in case we are running within a nested, external sub-pump).
|
| - BOOL ret = SetTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this),
|
| - delay_msec, NULL);
|
| - if (ret)
|
| - return;
|
| - // If we can't set timers, we are in big trouble... but cross our fingers for
|
| - // now.
|
| - // TODO(jar): If we don't see this error, use a CHECK() here instead.
|
| - UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", SET_TIMER_ERROR,
|
| - MESSAGE_LOOP_PROBLEM_MAX);
|
| + RescheduleTimer();
|
| }
|
|
|
| //-----------------------------------------------------------------------------
|
| @@ -318,6 +282,8 @@ void MessagePumpForUI::HandleWorkMessage() {
|
| // needs to do more work.
|
| if (state_->delegate->DoWork())
|
| ScheduleWork();
|
| + state_->delegate->DoDelayedWork(&delayed_work_time_);
|
| + RescheduleTimer();
|
| }
|
|
|
| void MessagePumpForUI::HandleTimerMessage() {
|
| @@ -330,9 +296,51 @@ void MessagePumpForUI::HandleTimerMessage() {
|
| 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_);
|
| + RescheduleTimer();
|
| +}
|
| +
|
| +void MessagePumpForUI::RescheduleTimer() {
|
| + if (delayed_work_time_.is_null())
|
| + return;
|
| + //
|
| + // 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
|
| + // mechanism because the application can enter modal windows loops where it
|
| + // is not running our MessageLoop; the only way to have our timers fire in
|
| + // these cases is to post messages there.
|
| + //
|
| + // To provide sub-10ms timers, we process timers directly from our run loop.
|
| + // For the common case, timers will be processed there as the run loop does
|
| + // its normal work. However, we *also* set the system timer so that WM_TIMER
|
| + // events fire. This mops up the case of timers not being able to work in
|
| + // modal message loops. It is possible for the SetTimer to pop and have no
|
| + // pending timers, because they could have already been processed by the
|
| + // run loop itself.
|
| + //
|
| + // We use a single SetTimer corresponding to the timer that will expire
|
| + // soonest. As new timers are created and destroyed, we update SetTimer.
|
| + // Getting a spurrious SetTimer event firing is benign, as we'll just be
|
| + // processing an empty timer queue.
|
| + //
|
| + int delay_msec = GetCurrentDelay();
|
| + DCHECK_GE(delay_msec, 0);
|
| + if (delay_msec == 0) {
|
| + ScheduleWork();
|
| + } else {
|
| + if (delay_msec < USER_TIMER_MINIMUM)
|
| + delay_msec = USER_TIMER_MINIMUM;
|
| +
|
| + // Create a WM_TIMER event that will wake us up to check for any pending
|
| + // timers (in case we are running within a nested, external sub-pump).
|
| + BOOL ret = SetTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this),
|
| + delay_msec, NULL);
|
| + if (ret)
|
| + return;
|
| + // If we can't set timers, we are in big trouble... but cross our fingers
|
| + // for now.
|
| + // TODO(jar): If we don't see this error, use a CHECK() here instead.
|
| + UMA_HISTOGRAM_ENUMERATION("Chrome.MessageLoopProblem", SET_TIMER_ERROR,
|
| + MESSAGE_LOOP_PROBLEM_MAX);
|
| }
|
| }
|
|
|
|
|