thread_restrictions.h revision 58537e28ecd584eab876aee8be7156509866d23a
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef BASE_THREADING_THREAD_RESTRICTIONS_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define BASE_THREADING_THREAD_RESTRICTIONS_H_ 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/base_export.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// See comment at top of thread_checker.h 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define ENABLE_THREAD_RESTRICTIONS 1 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ENABLE_THREAD_RESTRICTIONS 0 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class AcceleratedPresenter; 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BrowserProcessImpl; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class HistogramSynchronizer; 215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class MetricsService; 225e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class NativeBackendKWallet; 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ScopedAllowWaitForLegacyWebViewApi; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestingAutomationProvider; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace browser_sync { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NonFrontendDataTypeController; 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class UIModelWorker; 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace cc { 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class CompletionEvent; 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace chromeos { 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class AudioMixerAlsa; 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class BlockingMethodCaller; 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace system { 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class StatisticsProviderImpl; 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace chrome_browser_net { 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Predictor; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BrowserGpuChannelHostFactory; 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BrowserTestBase; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GLHelper; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GpuChannelHost; 485e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class NestedMessagePumpAndroid; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderWidgetHelper; 505e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class ScopedAllowWaitForAndroidLayoutTests; 515e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class TextInputClientMac; 525e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 535e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace dbus { 545e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class Bus; 555e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 565e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace disk_cache { 575e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class BackendImpl; 585e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class InFlightIO; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioOutputController; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FileStreamPosix; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FileStreamWin; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AddressTrackerLinux; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 715e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace remoting { 725e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class AutoThread; 735e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 755e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace base { 765e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 775e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace android { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class JavaHandlerThread; 795e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)} 805e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 815e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class SequencedWorkerPool; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SimpleThread; 835e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class Thread; 845e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class ThreadTestHelper; 855e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Certain behavior is disallowed on certain threads. ThreadRestrictions helps 875e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// enforce these rules. Examples of such rules: 885e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// 895e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// * Do not do blocking IO (makes the thread janky) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// * Do not access Singleton/LazyInstance (may lead to shutdown crashes) 915e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// 925e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// Here's more about how the protection works: 935e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1) If a thread should not be allowed to make IO calls, mark it: 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// base::ThreadRestrictions::SetIOAllowed(false); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// By default, threads *are* allowed to make IO calls. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// In Chrome browser code, IO calls should be proxied to the File thread. 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2) If a function makes a call that will go out to disk, check whether the 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// current thread is allowed: 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// base::ThreadRestrictions::AssertIOAllowed(); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Style tip: where should you put AssertIOAllowed checks? It's best 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// if you put them as close to the disk access as possible, at the 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// lowest level. This rule is simple to follow and helps catch all 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// callers. For example, if your function GoDoSomeBlockingDiskCall() 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// only calls other functions in Chrome and not fopen(), you should go 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// add the AssertIOAllowed checks in the helper functions. 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BASE_EXPORT ThreadRestrictions { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Constructing a ScopedAllowIO temporarily allows IO for the current 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // thread. Doing this is almost certainly always incorrect. 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class BASE_EXPORT ScopedAllowIO { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedAllowIO() { previous_value_ = SetIOAllowed(true); } 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~ScopedAllowIO() { SetIOAllowed(previous_value_); } 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether IO is allowed when the ScopedAllowIO was constructed. 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool previous_value_; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Constructing a ScopedAllowSingleton temporarily allows accessing for the 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // current thread. Doing this is almost always incorrect. 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class BASE_EXPORT ScopedAllowSingleton { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedAllowSingleton() { previous_value_ = SetSingletonAllowed(true); } 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~ScopedAllowSingleton() { SetSingletonAllowed(previous_value_); } 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether singleton use is allowed when the ScopedAllowSingleton was 1345e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) // constructed. 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool previous_value_; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1375e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedAllowSingleton); 1385e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) }; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if ENABLE_THREAD_RESTRICTIONS 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set whether the current thread to make IO calls. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Threads start out in the *allowed* state. 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns the previous value. 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool SetIOAllowed(bool allowed); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check whether the current thread is allowed to make IO calls, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and DCHECK if not. See the block comment above the class for 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a discussion of where to add these checks. 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void AssertIOAllowed(); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set whether the current thread can use singletons. Returns the previous 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // value. 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool SetSingletonAllowed(bool allowed); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1555e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) // Check whether the current thread is allowed to use singletons (Singleton / 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // LazyInstance). DCHECKs if not. 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static void AssertSingletonAllowed(); 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Disable waiting on the current thread. Threads start out in the *allowed* 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // state. Returns the previous value. 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void DisallowWaiting(); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check whether the current thread is allowed to wait, and DCHECK if not. 1645e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) static void AssertWaitAllowed(); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Inline the empty definitions of these functions so that they can be 167 // compiled out. 168 static bool SetIOAllowed(bool allowed) { return true; } 169 static void AssertIOAllowed() {} 170 static bool SetSingletonAllowed(bool allowed) { return true; } 171 static void AssertSingletonAllowed() {} 172 static void DisallowWaiting() {} 173 static void AssertWaitAllowed() {} 174#endif 175 176 private: 177 // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to jam or brettw first. 178 // BEGIN ALLOWED USAGE. 179 friend class content::BrowserTestBase; 180 friend class content::NestedMessagePumpAndroid; 181 friend class content::RenderWidgetHelper; 182 friend class content::ScopedAllowWaitForAndroidLayoutTests; 183 friend class ::HistogramSynchronizer; 184 friend class ::ScopedAllowWaitForLegacyWebViewApi; 185 friend class ::TestingAutomationProvider; 186 friend class cc::CompletionEvent; 187 friend class remoting::AutoThread; 188 friend class MessagePumpDefault; 189 friend class SequencedWorkerPool; 190 friend class SimpleThread; 191 friend class Thread; 192 friend class ThreadTestHelper; 193 friend class PlatformThread; 194 friend class android::JavaHandlerThread; 195 196 // END ALLOWED USAGE. 197 // BEGIN USAGE THAT NEEDS TO BE FIXED. 198 friend class ::chromeos::AudioMixerAlsa; // http://crbug.com/125206 199 friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360 200 friend class ::chromeos::system::StatisticsProviderImpl; // http://crbug.com/125385 201 friend class browser_sync::NonFrontendDataTypeController; // http://crbug.com/19757 202 friend class browser_sync::UIModelWorker; // http://crbug.com/19757 203 friend class chrome_browser_net::Predictor; // http://crbug.com/78451 204 friend class 205 content::BrowserGpuChannelHostFactory; // http://crbug.com/125248 206 friend class content::GLHelper; // http://crbug.com/125415 207 friend class content::GpuChannelHost; // http://crbug.com/125264 208 friend class content::TextInputClientMac; // http://crbug.com/121917 209 friend class dbus::Bus; // http://crbug.com/125222 210 friend class disk_cache::BackendImpl; // http://crbug.com/74623 211 friend class disk_cache::InFlightIO; // http://crbug.com/74623 212 friend class media::AudioOutputController; // http://crbug.com/120973 213 friend class net::FileStreamPosix; // http://crbug.com/115067 214 friend class net::FileStreamWin; // http://crbug.com/115067 215 friend class net::internal::AddressTrackerLinux; // http://crbug.com/125097 216 friend class ::AcceleratedPresenter; // http://crbug.com/125391 217 friend class ::BrowserProcessImpl; // http://crbug.com/125207 218 friend class ::MetricsService; // http://crbug.com/124954 219 friend class ::NativeBackendKWallet; // http://crbug.com/125331 220 // END USAGE THAT NEEDS TO BE FIXED. 221 222#if ENABLE_THREAD_RESTRICTIONS 223 static bool SetWaitAllowed(bool allowed); 224#else 225 static bool SetWaitAllowed(bool allowed) { return true; } 226#endif 227 228 // Constructing a ScopedAllowWait temporarily allows waiting on the current 229 // thread. Doing this is almost always incorrect, which is why we limit who 230 // can use this through friend. If you find yourself needing to use this, find 231 // another way. Talk to jam or brettw. 232 class BASE_EXPORT ScopedAllowWait { 233 public: 234 ScopedAllowWait() { previous_value_ = SetWaitAllowed(true); } 235 ~ScopedAllowWait() { SetWaitAllowed(previous_value_); } 236 private: 237 // Whether singleton use is allowed when the ScopedAllowWait was 238 // constructed. 239 bool previous_value_; 240 241 DISALLOW_COPY_AND_ASSIGN(ScopedAllowWait); 242 }; 243 244 DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions); 245}; 246 247} // namespace base 248 249#endif // BASE_THREADING_THREAD_RESTRICTIONS_H_ 250