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