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 
current()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 
ThreadHasCurrent()31 bool MessageLoop::ThreadHasCurrent() {
32   return lazy_tls_ptr.Pointer()->Get() != nullptr;
33 }
34 
SetAsCurrent()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 
ReleaseFromCurrent()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 
~MessageLoop()47 MessageLoop::~MessageLoop() {
48   if (lazy_tls_ptr.Pointer()->Get() == this)
49     lazy_tls_ptr.Pointer()->Set(nullptr);
50 }
51 
Run()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 
BreakLoop()59 void MessageLoop::BreakLoop() {
60   should_exit_ = true;
61 }
62 
63 }  // namespace brillo
64