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