diff options
author | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-19 20:28:03 +0000 |
---|---|---|
committer | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-19 20:28:03 +0000 |
commit | 5db27db7e09cf3f72c68a8ca668b96177c97101f (patch) | |
tree | 3cfcb4c2c3fdf7543564e94603f33d640167d25e /base | |
parent | fe23e9a748e6a1849f22d3d0add4502a3a41604f (diff) | |
download | chromium_src-5db27db7e09cf3f72c68a8ca668b96177c97101f.zip chromium_src-5db27db7e09cf3f72c68a8ca668b96177c97101f.tar.gz chromium_src-5db27db7e09cf3f72c68a8ca668b96177c97101f.tar.bz2 |
base: add a thread-safety assertion checker
ThreadAssertions lets us assert that the current thread is allowed to
make blocking calls. See the header for more background.
This change implements ThreadAssertions but doesn't turn it on for
any of Chrome.
BUG=59575
Review URL: http://codereview.chromium.org/3824006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63091 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/base.gypi | 2 | ||||
-rw-r--r-- | base/thread_local.h | 2 | ||||
-rw-r--r-- | base/thread_restrictions.cc | 42 | ||||
-rw-r--r-- | base/thread_restrictions.h | 47 |
4 files changed, 92 insertions, 1 deletions
diff --git a/base/base.gypi b/base/base.gypi index 2adb528..7280eb8 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -460,6 +460,8 @@ 'sync_socket.h', 'sync_socket_win.cc', 'sync_socket_posix.cc', + 'thread_restrictions.h', + 'thread_restrictions.cc', 'time_mac.cc', 'time_posix.cc', 'version.cc', diff --git a/base/thread_local.h b/base/thread_local.h index 3227c83..075e209 100644 --- a/base/thread_local.h +++ b/base/thread_local.h @@ -6,7 +6,7 @@ // sure that this is really the proper solution for what you're trying to // achieve. Don't prematurely optimize, most likely you can just use a Lock. // -// These classes implement a warpper around the platform's TLS storage +// These classes implement a wrapper around the platform's TLS storage // mechanism. On construction, they will allocate a TLS slot, and free the // TLS slot on destruction. No memory management (creation or destruction) is // handled. This means for uses of ThreadLocalPointer, you must correctly diff --git a/base/thread_restrictions.cc b/base/thread_restrictions.cc new file mode 100644 index 0000000..5be8ad7 --- /dev/null +++ b/base/thread_restrictions.cc @@ -0,0 +1,42 @@ +// Copyright (c) 2010 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/thread_restrictions.h" + +// This entire file is compiled out in Release mode. +#ifndef NDEBUG + +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/thread_local.h" + +namespace { + +static base::LazyInstance<base::ThreadLocalBoolean> + g_io_disallowed(base::LINKER_INITIALIZED); + +} // anonymous namespace + +namespace base { + +// static +void ThreadRestrictions::SetIOAllowed(bool allowed) { + g_io_disallowed.Get().Set(!allowed); +} + +// 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."; + } +} + +} // namespace base + +#endif // NDEBUG diff --git a/base/thread_restrictions.h b/base/thread_restrictions.h new file mode 100644 index 0000000..4aa2cd6 --- /dev/null +++ b/base/thread_restrictions.h @@ -0,0 +1,47 @@ +// Copyright (c) 2010 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. + +#ifndef BASE_THREAD_RESTRICTIONS_H_ +#define BASE_THREAD_RESTRICTIONS_H_ + +namespace base { + +// ThreadRestrictions helps protect threads that should not block from +// making blocking calls. It works like this: +// +// 1) If a thread should not be allowed to make IO calls, mark it: +// base::ThreadRestrictions::SetIOAllowed(false); +// By default, threads *are* allowed to make IO calls. +// In Chrome browser code, IO calls should be proxied to the File thread. +// +// 2) If a function makes a call that will go out to disk, check whether the +// current thread is allowed: +// base::ThreadRestrictions::AssertIOAllowed(); +// +// ThreadRestrictions does nothing in release builds; it is debug-only. +// +class ThreadRestrictions { + public: + // Set whether the current thread to make IO calls. + // Threads start out in the *allowed* state. + static void SetIOAllowed(bool allowed); + + // Check whether the current thread is allowed to make IO calls, + // and DCHECK if not. + static void AssertIOAllowed(); + + private: + ThreadRestrictions(); // class for namespacing only +}; + +// In Release builds, inline the empty definitions of these functions so +// that they can be compiled out. +#ifdef NDEBUG +void ThreadRestrictions::SetIOAllowed(bool allowed) {} +void ThreadRestrictions::AssertIOAllowed() {} +#endif + +} // namespace base + +#endif // BASE_THREAD_RESTRICTIONS_H_ |