blob: dbb92cf4485440d104717d87904c290308937d66 [file] [log] [blame]
Scott Graham894986a2018-06-14 14:15:50 -07001// Copyright 2018 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
Scott Graham76a8dc72018-06-18 13:37:29 -07005#include "util/msg_loop.h"
Scott Graham894986a2018-06-14 14:15:50 -07006
7#include "base/logging.h"
8
9namespace {
10
11thread_local MsgLoop* g_current;
12}
13
14MsgLoop::MsgLoop() {
15 DCHECK(g_current == nullptr);
16 g_current = this;
17}
18
19MsgLoop::~MsgLoop() {
20 DCHECK(g_current == this);
21 g_current = nullptr;
22}
23
24void MsgLoop::Run() {
25 while (!should_quit_) {
26 Task task;
27 {
28 std::unique_lock<std::mutex> queue_lock(queue_mutex_);
29 notifier_.wait(queue_lock, [this]() {
30 return (!task_queue_.empty()) || should_quit_;
31 });
32
33 if (should_quit_)
34 return;
35
36 task = std::move(task_queue_.front());
37 task_queue_.pop();
38 }
39
40 std::move(task).Run();
41 }
42}
43
44void MsgLoop::PostQuit() {
45 PostTask(
46 base::BindOnce([](MsgLoop* self) { self->should_quit_ = true; }, this));
47}
48
49void MsgLoop::PostTask(Task work) {
50 {
51 std::unique_lock<std::mutex> queue_lock(queue_mutex_);
52 task_queue_.emplace(std::move(work));
53 }
54
55 notifier_.notify_one();
56}
57
58void MsgLoop::RunUntilIdleForTesting() {
59 for (bool done = false; !done;) {
60 Task task;
61 {
62 std::unique_lock<std::mutex> queue_lock(queue_mutex_);
63 task = std::move(task_queue_.front());
64 task_queue_.pop();
65
66 if (task_queue_.empty())
67 done = true;
68 }
69
70 std::move(task).Run();
71 }
72}
73
74MsgLoop* MsgLoop::Current() {
75 return g_current;
76}