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 #if !defined(OS_ZOS) 12 thread_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 } 19 MsgLoop()20MsgLoop::MsgLoop() { 21 DCHECK(g_current == nullptr); 22 g_current = this; 23 } 24 ~MsgLoop()25MsgLoop::~MsgLoop() { 26 DCHECK(g_current == this); 27 g_current = nullptr; 28 } 29 Run()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 PostQuit()50void MsgLoop::PostQuit() { 51 PostTask([this]() { should_quit_ = true; }); 52 } 53 PostTask(std::function<void ()> work)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 RunUntilIdleForTesting()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 Current()79MsgLoop* MsgLoop::Current() { 80 return g_current; 81 } 82