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