xref: /third_party/gn/src/util/msg_loop.cc (revision 6d528ed9)
1// 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
5#include "util/msg_loop.h"
6
7#include "base/logging.h"
8
9namespace {
10
11#if !defined(OS_ZOS)
12thread_local MsgLoop* g_current;
13#else
14// TODO(gabylb) - zos: thread_local not yet supported, use zoslib's impl'n:
15__tlssim<MsgLoop*> __g_current_impl(nullptr);
16#define g_current (*__g_current_impl.access())
17#endif
18}  // namespace
19
20MsgLoop::MsgLoop() {
21  DCHECK(g_current == nullptr);
22  g_current = this;
23}
24
25MsgLoop::~MsgLoop() {
26  DCHECK(g_current == this);
27  g_current = nullptr;
28}
29
30void MsgLoop::Run() {
31  while (!should_quit_) {
32    std::function<void()> task;
33    {
34      std::unique_lock<std::mutex> queue_lock(queue_mutex_);
35      notifier_.wait(queue_lock, [this]() {
36        return (!task_queue_.empty()) || should_quit_;
37      });
38
39      if (should_quit_)
40        return;
41
42      task = std::move(task_queue_.front());
43      task_queue_.pop();
44    }
45
46    task();
47  }
48}
49
50void MsgLoop::PostQuit() {
51  PostTask([this]() { should_quit_ = true; });
52}
53
54void MsgLoop::PostTask(std::function<void()> work) {
55  {
56    std::unique_lock<std::mutex> queue_lock(queue_mutex_);
57    task_queue_.emplace(std::move(work));
58  }
59
60  notifier_.notify_one();
61}
62
63void MsgLoop::RunUntilIdleForTesting() {
64  for (bool done = false; !done;) {
65    std::function<void()> task;
66    {
67      std::unique_lock<std::mutex> queue_lock(queue_mutex_);
68      task = std::move(task_queue_.front());
69      task_queue_.pop();
70
71      if (task_queue_.empty())
72        done = true;
73    }
74
75    task();
76  }
77}
78
79MsgLoop* MsgLoop::Current() {
80  return g_current;
81}
82