summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-19 20:28:03 +0000
committerevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-19 20:28:03 +0000
commit5db27db7e09cf3f72c68a8ca668b96177c97101f (patch)
tree3cfcb4c2c3fdf7543564e94603f33d640167d25e /base
parentfe23e9a748e6a1849f22d3d0add4502a3a41604f (diff)
downloadchromium_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.gypi2
-rw-r--r--base/thread_local.h2
-rw-r--r--base/thread_restrictions.cc42
-rw-r--r--base/thread_restrictions.h47
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_