// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/threading/thread_restrictions.h" #if ENABLE_THREAD_RESTRICTIONS #include "base/lazy_instance.h" #include "base/logging.h" #include "base/threading/thread_local.h" namespace base { namespace { LazyInstance<ThreadLocalBoolean>::Leaky g_io_disallowed = LAZY_INSTANCE_INITIALIZER; LazyInstance<ThreadLocalBoolean>::Leaky g_singleton_disallowed = LAZY_INSTANCE_INITIALIZER; LazyInstance<ThreadLocalBoolean>::Leaky g_wait_disallowed = LAZY_INSTANCE_INITIALIZER; } // anonymous namespace // static bool ThreadRestrictions::SetIOAllowed(bool allowed) { bool previous_disallowed = g_io_disallowed.Get().Get(); g_io_disallowed.Get().Set(!allowed); return !previous_disallowed; } // static void ThreadRestrictions::AssertIOAllowed() { if (g_io_disallowed.Get().Get()) { LOG(FATAL) << "Function marked as IO-only was called from a thread that " "disallows IO! If this thread really should be allowed to " "make IO calls, adjust the call to " "base::ThreadRestrictions::SetIOAllowed() in this thread's " "startup."; } } // static bool ThreadRestrictions::SetSingletonAllowed(bool allowed) { bool previous_disallowed = g_singleton_disallowed.Get().Get(); g_singleton_disallowed.Get().Set(!allowed); return !previous_disallowed; } // static void ThreadRestrictions::AssertSingletonAllowed() { if (g_singleton_disallowed.Get().Get()) { LOG(FATAL) << "LazyInstance/Singleton is not allowed to be used on this " << "thread. Most likely it's because this thread is not " << "joinable, so AtExitManager may have deleted the object " << "on shutdown, leading to a potential shutdown crash."; } } // static void ThreadRestrictions::DisallowWaiting() { g_wait_disallowed.Get().Set(true); } // static void ThreadRestrictions::AssertWaitAllowed() { if (g_wait_disallowed.Get().Get()) { LOG(FATAL) << "Waiting is not allowed to be used on this thread to prevent" << "jank and deadlock."; } } bool ThreadRestrictions::SetWaitAllowed(bool allowed) { bool previous_disallowed = g_wait_disallowed.Get().Get(); g_wait_disallowed.Get().Set(!allowed); return !previous_disallowed; } } // namespace base #endif // ENABLE_THREAD_RESTRICTIONS