blob: 1797c903ce6f26794cc925ce12a6f4364fac3e1e [file] [log] [blame]
// 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<MsgLoop*> __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<void()> task;
{
std::unique_lock<std::mutex> 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<void()> work) {
{
std::unique_lock<std::mutex> queue_lock(queue_mutex_);
task_queue_.emplace(std::move(work));
}
notifier_.notify_one();
}
void MsgLoop::RunUntilIdleForTesting() {
for (bool done = false; !done;) {
std::function<void()> task;
{
std::unique_lock<std::mutex> 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;
}