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 ENABLE_THREAD_RESTRICTIONS
      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     LOG(FATAL) <<
     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     LOG(FATAL) << "LazyInstance/Singleton is not allowed to be used on this "
     58                << "thread.  Most likely it's because this thread is not "
     59                << "joinable, so AtExitManager may have deleted the object "
     60                << "on shutdown, leading to a potential shutdown crash.";
     61   }
     62 }
     63 
     64 // static
     65 void ThreadRestrictions::DisallowWaiting() {
     66   g_wait_disallowed.Get().Set(true);
     67 }
     68 
     69 // static
     70 void ThreadRestrictions::AssertWaitAllowed() {
     71   if (g_wait_disallowed.Get().Get()) {
     72     LOG(FATAL) << "Waiting is not allowed to be used on this thread to prevent "
     73                << "jank and deadlock.";
     74   }
     75 }
     76 
     77 bool ThreadRestrictions::SetWaitAllowed(bool allowed) {
     78   bool previous_disallowed = g_wait_disallowed.Get().Get();
     79   g_wait_disallowed.Get().Set(!allowed);
     80   return !previous_disallowed;
     81 }
     82 
     83 }  // namespace base
     84 
     85 #endif  // ENABLE_THREAD_RESTRICTIONS
     86