86 lines
2.4 KiB
C++
86 lines
2.4 KiB
C++
|
// 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
|