普通文本  |  64行  |  1.76 KB

// Copyright 2015 The Chromium OS 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 <brillo/message_loops/message_loop.h>

#include <base/lazy_instance.h>
#include <base/logging.h>
#include <base/threading/thread_local.h>

namespace brillo {

namespace {

// A lazily created thread local storage for quick access to a thread's message
// loop, if one exists.  This should be safe and free of static constructors.
base::LazyInstance<base::ThreadLocalPointer<MessageLoop> >::Leaky lazy_tls_ptr =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

const MessageLoop::TaskId MessageLoop::kTaskIdNull = 0;

MessageLoop* MessageLoop::current() {
  DCHECK(lazy_tls_ptr.Pointer()->Get() != nullptr) <<
      "There isn't a MessageLoop for this thread. You need to initialize it "
      "first.";
  return lazy_tls_ptr.Pointer()->Get();
}

bool MessageLoop::ThreadHasCurrent() {
  return lazy_tls_ptr.Pointer()->Get() != nullptr;
}

void MessageLoop::SetAsCurrent() {
  DCHECK(lazy_tls_ptr.Pointer()->Get() == nullptr) <<
      "There's already a MessageLoop for this thread.";
  lazy_tls_ptr.Pointer()->Set(this);
}

void MessageLoop::ReleaseFromCurrent() {
  DCHECK(lazy_tls_ptr.Pointer()->Get() == this) <<
      "This is not the MessageLoop bound to the current thread.";
  lazy_tls_ptr.Pointer()->Set(nullptr);
}

MessageLoop::~MessageLoop() {
  if (lazy_tls_ptr.Pointer()->Get() == this)
    lazy_tls_ptr.Pointer()->Set(nullptr);
}

void MessageLoop::Run() {
  // Default implementation is to call RunOnce() blocking until there aren't
  // more tasks scheduled.
  while (!should_exit_ && RunOnce(true)) {}
  should_exit_ = false;
}

void MessageLoop::BreakLoop() {
  should_exit_ = true;
}

}  // namespace brillo