Home | History | Annotate | Download | only in message_loops
      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