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