• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(OS_WIN)
10 #include "base/message_loop/message_pump_dispatcher.h"
11 #endif
12 
13 namespace base {
14 
RunLoop()15 RunLoop::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(OS_WIN)
25    dispatcher_ = NULL;
26 #endif
27 }
28 
29 #if defined(OS_WIN)
RunLoop(MessagePumpDispatcher * dispatcher)30 RunLoop::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 
~RunLoop()43 RunLoop::~RunLoop() {
44 }
45 
Run()46 void RunLoop::Run() {
47   if (!BeforeRun())
48     return;
49   loop_->RunHandler();
50   AfterRun();
51 }
52 
RunUntilIdle()53 void RunLoop::RunUntilIdle() {
54   quit_when_idle_received_ = true;
55   Run();
56 }
57 
Quit()58 void 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 
QuitClosure()66 base::Closure RunLoop::QuitClosure() {
67   return base::Bind(&RunLoop::Quit, weak_factory_.GetWeakPtr());
68 }
69 
BeforeRun()70 bool 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 
AfterRun()87 void 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