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