run_loop.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright (c) 2012 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/run_loop.h" 6 7#include "base/bind.h" 8 9#if defined(USE_AURA) 10#include "base/message_loop/message_pump_dispatcher.h" 11#endif 12 13namespace base { 14 15RunLoop::RunLoop() 16 : loop_(MessageLoop::current()), 17 previous_run_loop_(NULL), 18 run_depth_(0), 19 run_called_(false), 20 quit_called_(false), 21 running_(false), 22 quit_when_idle_received_(false), 23 weak_factory_(this) { 24#if defined(USE_AURA) 25 dispatcher_ = NULL; 26#endif 27} 28 29#if defined(USE_AURA) 30RunLoop::RunLoop(MessagePumpDispatcher* dispatcher) 31 : loop_(MessageLoop::current()), 32 previous_run_loop_(NULL), 33 dispatcher_(dispatcher), 34 run_depth_(0), 35 run_called_(false), 36 quit_called_(false), 37 running_(false), 38 quit_when_idle_received_(false), 39 weak_factory_(this) { 40} 41#endif 42 43RunLoop::~RunLoop() { 44} 45 46void RunLoop::Run() { 47 if (!BeforeRun()) 48 return; 49 loop_->RunHandler(); 50 AfterRun(); 51} 52 53void RunLoop::RunUntilIdle() { 54 quit_when_idle_received_ = true; 55 Run(); 56} 57 58void RunLoop::Quit() { 59 quit_called_ = true; 60 if (running_ && loop_->run_loop_ == this) { 61 // This is the inner-most RunLoop, so quit now. 62 loop_->QuitNow(); 63 } 64} 65 66base::Closure RunLoop::QuitClosure() { 67 return base::Bind(&RunLoop::Quit, weak_factory_.GetWeakPtr()); 68} 69 70bool RunLoop::BeforeRun() { 71 DCHECK(!run_called_); 72 run_called_ = true; 73 74 // Allow Quit to be called before Run. 75 if (quit_called_) 76 return false; 77 78 // Push RunLoop stack: 79 previous_run_loop_ = loop_->run_loop_; 80 run_depth_ = previous_run_loop_? previous_run_loop_->run_depth_ + 1 : 1; 81 loop_->run_loop_ = this; 82 83 running_ = true; 84 return true; 85} 86 87void RunLoop::AfterRun() { 88 running_ = false; 89 90 // Pop RunLoop stack: 91 loop_->run_loop_ = previous_run_loop_; 92 93 // Execute deferred QuitNow, if any: 94 if (previous_run_loop_ && previous_run_loop_->quit_called_) 95 loop_->QuitNow(); 96} 97 98} // namespace base 99