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