• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
9 namespace {
10 
11 thread_local MsgLoop* g_current;
12 }
13 
MsgLoop()14 MsgLoop::MsgLoop() {
15   DCHECK(g_current == nullptr);
16   g_current = this;
17 }
18 
~MsgLoop()19 MsgLoop::~MsgLoop() {
20   DCHECK(g_current == this);
21   g_current = nullptr;
22 }
23 
Run()24 void MsgLoop::Run() {
25   while (!should_quit_) {
26     std::function<void()> 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     task();
41   }
42 }
43 
PostQuit()44 void MsgLoop::PostQuit() {
45   PostTask([this]() { should_quit_ = true; });
46 }
47 
PostTask(std::function<void ()> work)48 void MsgLoop::PostTask(std::function<void()> work) {
49   {
50     std::unique_lock<std::mutex> queue_lock(queue_mutex_);
51     task_queue_.emplace(std::move(work));
52   }
53 
54   notifier_.notify_one();
55 }
56 
RunUntilIdleForTesting()57 void MsgLoop::RunUntilIdleForTesting() {
58   for (bool done = false; !done;) {
59     std::function<void()> task;
60     {
61       std::unique_lock<std::mutex> queue_lock(queue_mutex_);
62       task = std::move(task_queue_.front());
63       task_queue_.pop();
64 
65       if (task_queue_.empty())
66         done = true;
67     }
68 
69     task();
70   }
71 }
72 
Current()73 MsgLoop* MsgLoop::Current() {
74   return g_current;
75 }
76