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 11 namespace brillo { 12 13 namespace { 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. 17 base::LazyInstance<base::ThreadLocalPointer<MessageLoop> >::Leaky lazy_tls_ptr = 18 LAZY_INSTANCE_INITIALIZER; 19 20 } // namespace 21 22 const MessageLoop::TaskId MessageLoop::kTaskIdNull = 0; 23 24 MessageLoop* 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 31 bool MessageLoop::ThreadHasCurrent() { 32 return lazy_tls_ptr.Pointer()->Get() != nullptr; 33 } 34 35 void 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 41 void 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 47 MessageLoop::~MessageLoop() { 48 if (lazy_tls_ptr.Pointer()->Get() == this) 49 lazy_tls_ptr.Pointer()->Set(nullptr); 50 } 51 52 void 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 59 void MessageLoop::BreakLoop() { 60 should_exit_ = true; 61 } 62 63 } // namespace brillo 64