1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/threading/thread_restrictions.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,251 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef BASE_THREADING_THREAD_RESTRICTIONS_H_ 1.9 +#define BASE_THREADING_THREAD_RESTRICTIONS_H_ 1.10 + 1.11 +#include "base/base_export.h" 1.12 +#include "base/basictypes.h" 1.13 + 1.14 +// See comment at top of thread_checker.h 1.15 +#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) 1.16 +#define ENABLE_THREAD_RESTRICTIONS 1 1.17 +#else 1.18 +#define ENABLE_THREAD_RESTRICTIONS 0 1.19 +#endif 1.20 + 1.21 +class AcceleratedPresenter; 1.22 +class BrowserProcessImpl; 1.23 +class HistogramSynchronizer; 1.24 +class MetricsService; 1.25 +class NativeBackendKWallet; 1.26 +class ScopedAllowWaitForLegacyWebViewApi; 1.27 +class TestingAutomationProvider; 1.28 + 1.29 +namespace browser_sync { 1.30 +class NonFrontendDataTypeController; 1.31 +class UIModelWorker; 1.32 +} 1.33 +namespace cc { 1.34 +class CompletionEvent; 1.35 +} 1.36 +namespace chromeos { 1.37 +class AudioMixerAlsa; 1.38 +class BlockingMethodCaller; 1.39 +namespace system { 1.40 +class StatisticsProviderImpl; 1.41 +} 1.42 +} 1.43 +namespace chrome_browser_net { 1.44 +class Predictor; 1.45 +} 1.46 +namespace content { 1.47 +class BrowserGpuChannelHostFactory; 1.48 +class BrowserShutdownProfileDumper; 1.49 +class BrowserTestBase; 1.50 +class GLHelper; 1.51 +class GpuChannelHost; 1.52 +class NestedMessagePumpAndroid; 1.53 +class RenderWidgetHelper; 1.54 +class ScopedAllowWaitForAndroidLayoutTests; 1.55 +class TextInputClientMac; 1.56 +} 1.57 +namespace dbus { 1.58 +class Bus; 1.59 +} 1.60 +namespace disk_cache { 1.61 +class BackendImpl; 1.62 +class InFlightIO; 1.63 +} 1.64 +namespace media { 1.65 +class AudioOutputController; 1.66 +} 1.67 +namespace net { 1.68 +class FileStreamPosix; 1.69 +class FileStreamWin; 1.70 +namespace internal { 1.71 +class AddressTrackerLinux; 1.72 +} 1.73 +} 1.74 + 1.75 +namespace remoting { 1.76 +class AutoThread; 1.77 +} 1.78 + 1.79 +namespace base { 1.80 + 1.81 +namespace android { 1.82 +class JavaHandlerThread; 1.83 +} 1.84 + 1.85 +class SequencedWorkerPool; 1.86 +class SimpleThread; 1.87 +class Thread; 1.88 +class ThreadTestHelper; 1.89 + 1.90 +// Certain behavior is disallowed on certain threads. ThreadRestrictions helps 1.91 +// enforce these rules. Examples of such rules: 1.92 +// 1.93 +// * Do not do blocking IO (makes the thread janky) 1.94 +// * Do not access Singleton/LazyInstance (may lead to shutdown crashes) 1.95 +// 1.96 +// Here's more about how the protection works: 1.97 +// 1.98 +// 1) If a thread should not be allowed to make IO calls, mark it: 1.99 +// base::ThreadRestrictions::SetIOAllowed(false); 1.100 +// By default, threads *are* allowed to make IO calls. 1.101 +// In Chrome browser code, IO calls should be proxied to the File thread. 1.102 +// 1.103 +// 2) If a function makes a call that will go out to disk, check whether the 1.104 +// current thread is allowed: 1.105 +// base::ThreadRestrictions::AssertIOAllowed(); 1.106 +// 1.107 +// 1.108 +// Style tip: where should you put AssertIOAllowed checks? It's best 1.109 +// if you put them as close to the disk access as possible, at the 1.110 +// lowest level. This rule is simple to follow and helps catch all 1.111 +// callers. For example, if your function GoDoSomeBlockingDiskCall() 1.112 +// only calls other functions in Chrome and not fopen(), you should go 1.113 +// add the AssertIOAllowed checks in the helper functions. 1.114 + 1.115 +class BASE_EXPORT ThreadRestrictions { 1.116 + public: 1.117 + // Constructing a ScopedAllowIO temporarily allows IO for the current 1.118 + // thread. Doing this is almost certainly always incorrect. 1.119 + class BASE_EXPORT ScopedAllowIO { 1.120 + public: 1.121 + ScopedAllowIO() { previous_value_ = SetIOAllowed(true); } 1.122 + ~ScopedAllowIO() { SetIOAllowed(previous_value_); } 1.123 + private: 1.124 + // Whether IO is allowed when the ScopedAllowIO was constructed. 1.125 + bool previous_value_; 1.126 + 1.127 + DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO); 1.128 + }; 1.129 + 1.130 + // Constructing a ScopedAllowSingleton temporarily allows accessing for the 1.131 + // current thread. Doing this is almost always incorrect. 1.132 + class BASE_EXPORT ScopedAllowSingleton { 1.133 + public: 1.134 + ScopedAllowSingleton() { previous_value_ = SetSingletonAllowed(true); } 1.135 + ~ScopedAllowSingleton() { SetSingletonAllowed(previous_value_); } 1.136 + private: 1.137 + // Whether singleton use is allowed when the ScopedAllowSingleton was 1.138 + // constructed. 1.139 + bool previous_value_; 1.140 + 1.141 + DISALLOW_COPY_AND_ASSIGN(ScopedAllowSingleton); 1.142 + }; 1.143 + 1.144 +#if ENABLE_THREAD_RESTRICTIONS 1.145 + // Set whether the current thread to make IO calls. 1.146 + // Threads start out in the *allowed* state. 1.147 + // Returns the previous value. 1.148 + static bool SetIOAllowed(bool allowed); 1.149 + 1.150 + // Check whether the current thread is allowed to make IO calls, 1.151 + // and DCHECK if not. See the block comment above the class for 1.152 + // a discussion of where to add these checks. 1.153 + static void AssertIOAllowed(); 1.154 + 1.155 + // Set whether the current thread can use singletons. Returns the previous 1.156 + // value. 1.157 + static bool SetSingletonAllowed(bool allowed); 1.158 + 1.159 + // Check whether the current thread is allowed to use singletons (Singleton / 1.160 + // LazyInstance). DCHECKs if not. 1.161 + static void AssertSingletonAllowed(); 1.162 + 1.163 + // Disable waiting on the current thread. Threads start out in the *allowed* 1.164 + // state. Returns the previous value. 1.165 + static void DisallowWaiting(); 1.166 + 1.167 + // Check whether the current thread is allowed to wait, and DCHECK if not. 1.168 + static void AssertWaitAllowed(); 1.169 +#else 1.170 + // Inline the empty definitions of these functions so that they can be 1.171 + // compiled out. 1.172 + static bool SetIOAllowed(bool allowed) { return true; } 1.173 + static void AssertIOAllowed() {} 1.174 + static bool SetSingletonAllowed(bool allowed) { return true; } 1.175 + static void AssertSingletonAllowed() {} 1.176 + static void DisallowWaiting() {} 1.177 + static void AssertWaitAllowed() {} 1.178 +#endif 1.179 + 1.180 + private: 1.181 + // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to jam or brettw first. 1.182 + // BEGIN ALLOWED USAGE. 1.183 + friend class content::BrowserShutdownProfileDumper; 1.184 + friend class content::BrowserTestBase; 1.185 + friend class content::NestedMessagePumpAndroid; 1.186 + friend class content::RenderWidgetHelper; 1.187 + friend class content::ScopedAllowWaitForAndroidLayoutTests; 1.188 + friend class ::HistogramSynchronizer; 1.189 + friend class ::ScopedAllowWaitForLegacyWebViewApi; 1.190 + friend class ::TestingAutomationProvider; 1.191 + friend class cc::CompletionEvent; 1.192 + friend class remoting::AutoThread; 1.193 + friend class MessagePumpDefault; 1.194 + friend class SequencedWorkerPool; 1.195 + friend class SimpleThread; 1.196 + friend class Thread; 1.197 + friend class ThreadTestHelper; 1.198 + friend class PlatformThread; 1.199 + friend class android::JavaHandlerThread; 1.200 + 1.201 + // END ALLOWED USAGE. 1.202 + // BEGIN USAGE THAT NEEDS TO BE FIXED. 1.203 + friend class ::chromeos::AudioMixerAlsa; // http://crbug.com/125206 1.204 + friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360 1.205 + friend class ::chromeos::system::StatisticsProviderImpl; // http://crbug.com/125385 1.206 + friend class browser_sync::NonFrontendDataTypeController; // http://crbug.com/19757 1.207 + friend class browser_sync::UIModelWorker; // http://crbug.com/19757 1.208 + friend class chrome_browser_net::Predictor; // http://crbug.com/78451 1.209 + friend class 1.210 + content::BrowserGpuChannelHostFactory; // http://crbug.com/125248 1.211 + friend class content::GLHelper; // http://crbug.com/125415 1.212 + friend class content::GpuChannelHost; // http://crbug.com/125264 1.213 + friend class content::TextInputClientMac; // http://crbug.com/121917 1.214 + friend class dbus::Bus; // http://crbug.com/125222 1.215 + friend class disk_cache::BackendImpl; // http://crbug.com/74623 1.216 + friend class disk_cache::InFlightIO; // http://crbug.com/74623 1.217 + friend class media::AudioOutputController; // http://crbug.com/120973 1.218 + friend class net::FileStreamPosix; // http://crbug.com/115067 1.219 + friend class net::FileStreamWin; // http://crbug.com/115067 1.220 + friend class net::internal::AddressTrackerLinux; // http://crbug.com/125097 1.221 + friend class ::AcceleratedPresenter; // http://crbug.com/125391 1.222 + friend class ::BrowserProcessImpl; // http://crbug.com/125207 1.223 + friend class ::MetricsService; // http://crbug.com/124954 1.224 + friend class ::NativeBackendKWallet; // http://crbug.com/125331 1.225 + // END USAGE THAT NEEDS TO BE FIXED. 1.226 + 1.227 +#if ENABLE_THREAD_RESTRICTIONS 1.228 + static bool SetWaitAllowed(bool allowed); 1.229 +#else 1.230 + static bool SetWaitAllowed(bool allowed) { return true; } 1.231 +#endif 1.232 + 1.233 + // Constructing a ScopedAllowWait temporarily allows waiting on the current 1.234 + // thread. Doing this is almost always incorrect, which is why we limit who 1.235 + // can use this through friend. If you find yourself needing to use this, find 1.236 + // another way. Talk to jam or brettw. 1.237 + class BASE_EXPORT ScopedAllowWait { 1.238 + public: 1.239 + ScopedAllowWait() { previous_value_ = SetWaitAllowed(true); } 1.240 + ~ScopedAllowWait() { SetWaitAllowed(previous_value_); } 1.241 + private: 1.242 + // Whether singleton use is allowed when the ScopedAllowWait was 1.243 + // constructed. 1.244 + bool previous_value_; 1.245 + 1.246 + DISALLOW_COPY_AND_ASSIGN(ScopedAllowWait); 1.247 + }; 1.248 + 1.249 + DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions); 1.250 +}; 1.251 + 1.252 +} // namespace base 1.253 + 1.254 +#endif // BASE_THREADING_THREAD_RESTRICTIONS_H_