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