Fix race in WebRTC logging.
[chromium-blink-merge.git] / base / run_loop.cc
blob8344aa41b1631f6946e242e9ef0efbafdee23279
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.
5 #include "base/run_loop.h"
7 #include "base/bind.h"
9 #if defined(OS_WIN)
10 #include "base/message_loop/message_pump_dispatcher.h"
11 #endif
13 namespace base {
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
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) {
41 #endif
43 RunLoop::~RunLoop() {
46 void RunLoop::Run() {
47 if (!BeforeRun())
48 return;
49 loop_->RunHandler();
50 AfterRun();
53 void RunLoop::RunUntilIdle() {
54 quit_when_idle_received_ = true;
55 Run();
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();
66 base::Closure RunLoop::QuitClosure() {
67 return base::Bind(&RunLoop::Quit, weak_factory_.GetWeakPtr());
70 bool RunLoop::BeforeRun() {
71 DCHECK(!run_called_);
72 run_called_ = true;
74 // Allow Quit to be called before Run.
75 if (quit_called_)
76 return false;
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;
83 running_ = true;
84 return true;
87 void RunLoop::AfterRun() {
88 running_ = false;
90 // Pop RunLoop stack:
91 loop_->run_loop_ = previous_run_loop_;
93 // Execute deferred QuitNow, if any:
94 if (previous_run_loop_ && previous_run_loop_->quit_called_)
95 loop_->QuitNow();
98 } // namespace base