thread_restrictions.h revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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#ifndef BASE_THREADING_THREAD_RESTRICTIONS_H_ 6#define BASE_THREADING_THREAD_RESTRICTIONS_H_ 7 8#include "base/base_export.h" 9#include "base/basictypes.h" 10 11// See comment at top of thread_checker.h 12#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) 13#define ENABLE_THREAD_RESTRICTIONS 1 14#else 15#define ENABLE_THREAD_RESTRICTIONS 0 16#endif 17 18class AcceleratedPresenter; 19class BrowserProcessImpl; 20class HistogramSynchronizer; 21class MetricsService; 22class NativeBackendKWallet; 23class ScopedAllowWaitForLegacyWebViewApi; 24class TestingAutomationProvider; 25 26namespace browser_sync { 27class NonFrontendDataTypeController; 28class UIModelWorker; 29} 30namespace cc { 31class CompletionEvent; 32} 33namespace chromeos { 34class AudioMixerAlsa; 35class BlockingMethodCaller; 36namespace system { 37class StatisticsProviderImpl; 38} 39} 40namespace chrome_browser_net { 41class Predictor; 42} 43namespace content { 44class BrowserGpuChannelHostFactory; 45class BrowserShutdownProfileDumper; 46class BrowserTestBase; 47class GLHelper; 48class GpuChannelHost; 49class NestedMessagePumpAndroid; 50class RenderWidgetResizeHelper; 51class ScopedAllowWaitForAndroidLayoutTests; 52class TextInputClientMac; 53} 54namespace dbus { 55class Bus; 56} 57namespace disk_cache { 58class BackendImpl; 59class InFlightIO; 60} 61namespace media { 62class AudioOutputController; 63} 64namespace mojo { 65namespace common { 66class WatcherThreadManager; 67} 68} 69namespace net { 70class FileStreamPosix; 71class FileStreamWin; 72namespace internal { 73class AddressTrackerLinux; 74} 75} 76 77namespace remoting { 78class AutoThread; 79} 80 81namespace base { 82 83namespace android { 84class JavaHandlerThread; 85} 86 87class SequencedWorkerPool; 88class SimpleThread; 89class Thread; 90class ThreadTestHelper; 91 92// Certain behavior is disallowed on certain threads. ThreadRestrictions helps 93// enforce these rules. Examples of such rules: 94// 95// * Do not do blocking IO (makes the thread janky) 96// * Do not access Singleton/LazyInstance (may lead to shutdown crashes) 97// 98// Here's more about how the protection works: 99// 100// 1) If a thread should not be allowed to make IO calls, mark it: 101// base::ThreadRestrictions::SetIOAllowed(false); 102// By default, threads *are* allowed to make IO calls. 103// In Chrome browser code, IO calls should be proxied to the File thread. 104// 105// 2) If a function makes a call that will go out to disk, check whether the 106// current thread is allowed: 107// base::ThreadRestrictions::AssertIOAllowed(); 108// 109// 110// Style tip: where should you put AssertIOAllowed checks? It's best 111// if you put them as close to the disk access as possible, at the 112// lowest level. This rule is simple to follow and helps catch all 113// callers. For example, if your function GoDoSomeBlockingDiskCall() 114// only calls other functions in Chrome and not fopen(), you should go 115// add the AssertIOAllowed checks in the helper functions. 116 117class BASE_EXPORT ThreadRestrictions { 118 public: 119 // Constructing a ScopedAllowIO temporarily allows IO for the current 120 // thread. Doing this is almost certainly always incorrect. 121 class BASE_EXPORT ScopedAllowIO { 122 public: 123 ScopedAllowIO() { previous_value_ = SetIOAllowed(true); } 124 ~ScopedAllowIO() { SetIOAllowed(previous_value_); } 125 private: 126 // Whether IO is allowed when the ScopedAllowIO was constructed. 127 bool previous_value_; 128 129 DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO); 130 }; 131 132 // Constructing a ScopedAllowSingleton temporarily allows accessing for the 133 // current thread. Doing this is almost always incorrect. 134 class BASE_EXPORT ScopedAllowSingleton { 135 public: 136 ScopedAllowSingleton() { previous_value_ = SetSingletonAllowed(true); } 137 ~ScopedAllowSingleton() { SetSingletonAllowed(previous_value_); } 138 private: 139 // Whether singleton use is allowed when the ScopedAllowSingleton was 140 // constructed. 141 bool previous_value_; 142 143 DISALLOW_COPY_AND_ASSIGN(ScopedAllowSingleton); 144 }; 145 146#if ENABLE_THREAD_RESTRICTIONS 147 // Set whether the current thread to make IO calls. 148 // Threads start out in the *allowed* state. 149 // Returns the previous value. 150 static bool SetIOAllowed(bool allowed); 151 152 // Check whether the current thread is allowed to make IO calls, 153 // and DCHECK if not. See the block comment above the class for 154 // a discussion of where to add these checks. 155 static void AssertIOAllowed(); 156 157 // Set whether the current thread can use singletons. Returns the previous 158 // value. 159 static bool SetSingletonAllowed(bool allowed); 160 161 // Check whether the current thread is allowed to use singletons (Singleton / 162 // LazyInstance). DCHECKs if not. 163 static void AssertSingletonAllowed(); 164 165 // Disable waiting on the current thread. Threads start out in the *allowed* 166 // state. Returns the previous value. 167 static void DisallowWaiting(); 168 169 // Check whether the current thread is allowed to wait, and DCHECK if not. 170 static void AssertWaitAllowed(); 171#else 172 // Inline the empty definitions of these functions so that they can be 173 // compiled out. 174 static bool SetIOAllowed(bool allowed) { return true; } 175 static void AssertIOAllowed() {} 176 static bool SetSingletonAllowed(bool allowed) { return true; } 177 static void AssertSingletonAllowed() {} 178 static void DisallowWaiting() {} 179 static void AssertWaitAllowed() {} 180#endif 181 182 private: 183 // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to jam or brettw first. 184 // BEGIN ALLOWED USAGE. 185 friend class content::BrowserShutdownProfileDumper; 186 friend class content::BrowserTestBase; 187 friend class content::NestedMessagePumpAndroid; 188 friend class content::RenderWidgetResizeHelper; 189 friend class content::ScopedAllowWaitForAndroidLayoutTests; 190 friend class ::HistogramSynchronizer; 191 friend class ::ScopedAllowWaitForLegacyWebViewApi; 192 friend class ::TestingAutomationProvider; 193 friend class cc::CompletionEvent; 194 friend class mojo::common::WatcherThreadManager; 195 friend class remoting::AutoThread; 196 friend class MessagePumpDefault; 197 friend class SequencedWorkerPool; 198 friend class SimpleThread; 199 friend class Thread; 200 friend class ThreadTestHelper; 201 friend class PlatformThread; 202 friend class android::JavaHandlerThread; 203 204 // END ALLOWED USAGE. 205 // BEGIN USAGE THAT NEEDS TO BE FIXED. 206 friend class ::chromeos::AudioMixerAlsa; // http://crbug.com/125206 207 friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360 208 friend class ::chromeos::system::StatisticsProviderImpl; // http://crbug.com/125385 209 friend class browser_sync::NonFrontendDataTypeController; // http://crbug.com/19757 210 friend class browser_sync::UIModelWorker; // http://crbug.com/19757 211 friend class chrome_browser_net::Predictor; // http://crbug.com/78451 212 friend class 213 content::BrowserGpuChannelHostFactory; // http://crbug.com/125248 214 friend class content::GLHelper; // http://crbug.com/125415 215 friend class content::GpuChannelHost; // http://crbug.com/125264 216 friend class content::TextInputClientMac; // http://crbug.com/121917 217 friend class dbus::Bus; // http://crbug.com/125222 218 friend class disk_cache::BackendImpl; // http://crbug.com/74623 219 friend class disk_cache::InFlightIO; // http://crbug.com/74623 220 friend class media::AudioOutputController; // http://crbug.com/120973 221 friend class net::FileStreamPosix; // http://crbug.com/115067 222 friend class net::FileStreamWin; // http://crbug.com/115067 223 friend class net::internal::AddressTrackerLinux; // http://crbug.com/125097 224 friend class ::AcceleratedPresenter; // http://crbug.com/125391 225 friend class ::BrowserProcessImpl; // http://crbug.com/125207 226 friend class ::MetricsService; // http://crbug.com/124954 227 friend class ::NativeBackendKWallet; // http://crbug.com/125331 228 // END USAGE THAT NEEDS TO BE FIXED. 229 230#if ENABLE_THREAD_RESTRICTIONS 231 static bool SetWaitAllowed(bool allowed); 232#else 233 static bool SetWaitAllowed(bool allowed) { return true; } 234#endif 235 236 // Constructing a ScopedAllowWait temporarily allows waiting on the current 237 // thread. Doing this is almost always incorrect, which is why we limit who 238 // can use this through friend. If you find yourself needing to use this, find 239 // another way. Talk to jam or brettw. 240 class BASE_EXPORT ScopedAllowWait { 241 public: 242 ScopedAllowWait() { previous_value_ = SetWaitAllowed(true); } 243 ~ScopedAllowWait() { SetWaitAllowed(previous_value_); } 244 private: 245 // Whether singleton use is allowed when the ScopedAllowWait was 246 // constructed. 247 bool previous_value_; 248 249 DISALLOW_COPY_AND_ASSIGN(ScopedAllowWait); 250 }; 251 252 DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions); 253}; 254 255} // namespace base 256 257#endif // BASE_THREADING_THREAD_RESTRICTIONS_H_ 258