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()14MsgLoop::MsgLoop() { 15 DCHECK(g_current == nullptr); 16 g_current = this; 17 } 18 ~MsgLoop()19MsgLoop::~MsgLoop() { 20 DCHECK(g_current == this); 21 g_current = nullptr; 22 } 23 Run()24void 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()44void MsgLoop::PostQuit() { 45 PostTask([this]() { should_quit_ = true; }); 46 } 47 PostTask(std::function<void ()> work)48void 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()57void 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()73MsgLoop* MsgLoop::Current() { 74 return g_current; 75 } 76