Home | History | Annotate | Download | only in threading
      1 // Copyright (c) 2012 The Chromium 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 "base/threading/thread_restrictions.h"
      6 
      7 #if DCHECK_IS_ON()
      8 
      9 #include "base/lazy_instance.h"
     10 #include "base/logging.h"
     11 #include "base/threading/thread_local.h"
     12 
     13 namespace base {
     14 
     15 namespace {
     16 
     17 LazyInstance<ThreadLocalBoolean>::Leaky
     18     g_io_disallowed = LAZY_INSTANCE_INITIALIZER;
     19 
     20 LazyInstance<ThreadLocalBoolean>::Leaky
     21     g_singleton_disallowed = LAZY_INSTANCE_INITIALIZER;
     22 
     23 LazyInstance<ThreadLocalBoolean>::Leaky
     24     g_wait_disallowed = LAZY_INSTANCE_INITIALIZER;
     25 
     26 }  // namespace
     27 
     28 // static
     29 bool ThreadRestrictions::SetIOAllowed(bool allowed) {
     30   bool previous_disallowed = g_io_disallowed.Get().Get();
     31   g_io_disallowed.Get().Set(!allowed);
     32   return !previous_disallowed;
     33 }
     34 
     35 // static
     36 void ThreadRestrictions::AssertIOAllowed() {
     37   if (g_io_disallowed.Get().Get()) {
     38     NOTREACHED() <<
     39         "Function marked as IO-only was called from a thread that "
     40         "disallows IO!  If this thread really should be allowed to "
     41         "make IO calls, adjust the call to "
     42         "base::ThreadRestrictions::SetIOAllowed() in this thread's "
     43         "startup.";
     44   }
     45 }
     46 
     47 // static
     48 bool ThreadRestrictions::SetSingletonAllowed(bool allowed) {
     49   bool previous_disallowed = g_singleton_disallowed.Get().Get();
     50   g_singleton_disallowed.Get().Set(!allowed);
     51   return !previous_disallowed;
     52 }
     53 
     54 // static
     55 void ThreadRestrictions::AssertSingletonAllowed() {
     56   if (g_singleton_disallowed.Get().Get()) {
     57     NOTREACHED() << "LazyInstance/Singleton is not allowed to be used on this "
     58                  << "thread.  Most likely it's because this thread is not "
     59                  << "joinable (or the current task is running with "
     60                  << "TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN semantics), so "
     61                  << "AtExitManager may have deleted the object on shutdown, "
     62                  << "leading to a potential shutdown crash. If you need to use "
     63                  << "the object from this context, it'll have to be updated to "
     64                  << "use Leaky traits.";
     65   }
     66 }
     67 
     68 // static
     69 void ThreadRestrictions::DisallowWaiting() {
     70   g_wait_disallowed.Get().Set(true);
     71 }
     72 
     73 // static
     74 void ThreadRestrictions::AssertWaitAllowed() {
     75   if (g_wait_disallowed.Get().Get()) {
     76     NOTREACHED() << "Waiting is not allowed to be used on this thread to "
     77                  << "prevent jank and deadlock.";
     78   }
     79 }
     80 
     81 bool ThreadRestrictions::SetWaitAllowed(bool allowed) {
     82   bool previous_disallowed = g_wait_disallowed.Get().Get();
     83   g_wait_disallowed.Get().Set(!allowed);
     84   return !previous_disallowed;
     85 }
     86 
     87 }  // namespace base
     88 
     89 #endif  // DCHECK_IS_ON()
     90