1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/run_loop.h"
#include "base/bind.h"
#if defined(USE_AURA)
#include "base/message_loop/message_pump_dispatcher.h"
#endif
namespace base {
RunLoop::RunLoop()
: loop_(MessageLoop::current()),
previous_run_loop_(NULL),
run_depth_(0),
run_called_(false),
quit_called_(false),
running_(false),
quit_when_idle_received_(false),
weak_factory_(this) {
#if defined(USE_AURA)
dispatcher_ = NULL;
#endif
}
#if defined(USE_AURA)
RunLoop::RunLoop(MessagePumpDispatcher* dispatcher)
: loop_(MessageLoop::current()),
previous_run_loop_(NULL),
dispatcher_(dispatcher),
run_depth_(0),
run_called_(false),
quit_called_(false),
running_(false),
quit_when_idle_received_(false),
weak_factory_(this) {
}
#endif
RunLoop::~RunLoop() {
}
void RunLoop::Run() {
if (!BeforeRun())
return;
loop_->RunHandler();
AfterRun();
}
void RunLoop::RunUntilIdle() {
quit_when_idle_received_ = true;
Run();
}
void RunLoop::Quit() {
quit_called_ = true;
if (running_ && loop_->run_loop_ == this) {
// This is the inner-most RunLoop, so quit now.
loop_->QuitNow();
}
}
base::Closure RunLoop::QuitClosure() {
return base::Bind(&RunLoop::Quit, weak_factory_.GetWeakPtr());
}
bool RunLoop::BeforeRun() {
DCHECK(!run_called_);
run_called_ = true;
// Allow Quit to be called before Run.
if (quit_called_)
return false;
// Push RunLoop stack:
previous_run_loop_ = loop_->run_loop_;
run_depth_ = previous_run_loop_? previous_run_loop_->run_depth_ + 1 : 1;
loop_->run_loop_ = this;
running_ = true;
return true;
}
void RunLoop::AfterRun() {
running_ = false;
// Pop RunLoop stack:
loop_->run_loop_ = previous_run_loop_;
// Execute deferred QuitNow, if any:
if (previous_run_loop_ && previous_run_loop_->quit_called_)
loop_->QuitNow();
}
} // namespace base
|