// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "util/msg_loop.h" #include "base/logging.h" namespace { #if !defined(OS_ZOS) thread_local MsgLoop* g_current; #else // TODO(gabylb) - zos: thread_local not yet supported, use zoslib's impl'n: __tlssim __g_current_impl(nullptr); #define g_current (*__g_current_impl.access()) #endif } MsgLoop::MsgLoop() { DCHECK(g_current == nullptr); g_current = this; } MsgLoop::~MsgLoop() { DCHECK(g_current == this); g_current = nullptr; } void MsgLoop::Run() { while (!should_quit_) { std::function task; { std::unique_lock queue_lock(queue_mutex_); notifier_.wait(queue_lock, [this]() { return (!task_queue_.empty()) || should_quit_; }); if (should_quit_) return; task = std::move(task_queue_.front()); task_queue_.pop(); } task(); } } void MsgLoop::PostQuit() { PostTask([this]() { should_quit_ = true; }); } void MsgLoop::PostTask(std::function work) { { std::unique_lock queue_lock(queue_mutex_); task_queue_.emplace(std::move(work)); } notifier_.notify_one(); } void MsgLoop::RunUntilIdleForTesting() { for (bool done = false; !done;) { std::function task; { std::unique_lock queue_lock(queue_mutex_); task = std::move(task_queue_.front()); task_queue_.pop(); if (task_queue_.empty()) done = true; } task(); } } MsgLoop* MsgLoop::Current() { return g_current; }