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