1// Copyright 2015 The Chromium OS 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 <brillo/message_loops/message_loop.h> 6 7#include <base/lazy_instance.h> 8#include <base/logging.h> 9#include <base/threading/thread_local.h> 10 11namespace brillo { 12 13namespace { 14 15// A lazily created thread local storage for quick access to a thread's message 16// loop, if one exists. This should be safe and free of static constructors. 17base::LazyInstance<base::ThreadLocalPointer<MessageLoop> >::Leaky lazy_tls_ptr = 18 LAZY_INSTANCE_INITIALIZER; 19 20} // namespace 21 22const MessageLoop::TaskId MessageLoop::kTaskIdNull = 0; 23 24MessageLoop* MessageLoop::current() { 25 DCHECK(lazy_tls_ptr.Pointer()->Get() != nullptr) << 26 "There isn't a MessageLoop for this thread. You need to initialize it " 27 "first."; 28 return lazy_tls_ptr.Pointer()->Get(); 29} 30 31bool MessageLoop::ThreadHasCurrent() { 32 return lazy_tls_ptr.Pointer()->Get() != nullptr; 33} 34 35void MessageLoop::SetAsCurrent() { 36 DCHECK(lazy_tls_ptr.Pointer()->Get() == nullptr) << 37 "There's already a MessageLoop for this thread."; 38 lazy_tls_ptr.Pointer()->Set(this); 39} 40 41void MessageLoop::ReleaseFromCurrent() { 42 DCHECK(lazy_tls_ptr.Pointer()->Get() == this) << 43 "This is not the MessageLoop bound to the current thread."; 44 lazy_tls_ptr.Pointer()->Set(nullptr); 45} 46 47MessageLoop::~MessageLoop() { 48 if (lazy_tls_ptr.Pointer()->Get() == this) 49 lazy_tls_ptr.Pointer()->Set(nullptr); 50} 51 52void MessageLoop::Run() { 53 // Default implementation is to call RunOnce() blocking until there aren't 54 // more tasks scheduled. 55 while (!should_exit_ && RunOnce(true)) {} 56 should_exit_ = false; 57} 58 59void MessageLoop::BreakLoop() { 60 should_exit_ = true; 61} 62 63} // namespace brillo 64