Home | History | Annotate | Download | only in message_loop
      1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/message_loop/message_pump_default.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/threading/thread_restrictions.h"
      9 #include "build/build_config.h"
     10 
     11 #if defined(OS_MACOSX)
     12 #include "base/mac/scoped_nsautorelease_pool.h"
     13 #endif
     14 
     15 namespace base {
     16 
     17 MessagePumpDefault::MessagePumpDefault()
     18     : keep_running_(true),
     19       event_(false, false) {
     20 }
     21 
     22 MessagePumpDefault::~MessagePumpDefault() {
     23 }
     24 
     25 void MessagePumpDefault::Run(Delegate* delegate) {
     26   DCHECK(keep_running_) << "Quit must have been called outside of Run!";
     27 
     28   for (;;) {
     29 #if defined(OS_MACOSX)
     30     mac::ScopedNSAutoreleasePool autorelease_pool;
     31 #endif
     32 
     33     bool did_work = delegate->DoWork();
     34     if (!keep_running_)
     35       break;
     36 
     37     did_work |= delegate->DoDelayedWork(&delayed_work_time_);
     38     if (!keep_running_)
     39       break;
     40 
     41     if (did_work)
     42       continue;
     43 
     44     did_work = delegate->DoIdleWork();
     45     if (!keep_running_)
     46       break;
     47 
     48     if (did_work)
     49       continue;
     50 
     51     ThreadRestrictions::ScopedAllowWait allow_wait;
     52     if (delayed_work_time_.is_null()) {
     53       event_.Wait();
     54     } else {
     55       TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
     56       if (delay > TimeDelta()) {
     57         event_.TimedWait(delay);
     58       } else {
     59         // It looks like delayed_work_time_ indicates a time in the past, so we
     60         // need to call DoDelayedWork now.
     61         delayed_work_time_ = TimeTicks();
     62       }
     63     }
     64     // Since event_ is auto-reset, we don't need to do anything special here
     65     // other than service each delegate method.
     66   }
     67 
     68   keep_running_ = true;
     69 }
     70 
     71 void MessagePumpDefault::Quit() {
     72   keep_running_ = false;
     73 }
     74 
     75 void MessagePumpDefault::ScheduleWork() {
     76   // Since this can be called on any thread, we need to ensure that our Run
     77   // loop wakes up.
     78   event_.Signal();
     79 }
     80 
     81 void MessagePumpDefault::ScheduleDelayedWork(
     82     const TimeTicks& delayed_work_time) {
     83   // We know that we can't be blocked on Wait right now since this method can
     84   // only be called on the same thread as Run, so we only need to update our
     85   // record of how long to sleep when we do sleep.
     86   delayed_work_time_ = delayed_work_time;
     87 }
     88 
     89 }  // namespace base
     90