8344aa41b1631f6946e242e9ef0efbafdee23279
[platform/framework/web/crosswalk.git] / src / base / run_loop.cc
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
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)
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
43 RunLoop::~RunLoop() {
44 }
45
46 void RunLoop::Run() {
47   if (!BeforeRun())
48     return;
49   loop_->RunHandler();
50   AfterRun();
51 }
52
53 void RunLoop::RunUntilIdle() {
54   quit_when_idle_received_ = true;
55   Run();
56 }
57
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
66 base::Closure RunLoop::QuitClosure() {
67   return base::Bind(&RunLoop::Quit, weak_factory_.GetWeakPtr());
68 }
69
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
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