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/gtest_prod_util.h" 10 #include "base/logging.h" 11 #include "base/macros.h" 12 13 class BrowserProcessImpl; 14 class HistogramSynchronizer; 15 class NativeBackendKWallet; 16 class KeyStorageLinux; 17 18 namespace android_webview { 19 class AwFormDatabaseService; 20 class CookieManager; 21 class ScopedAllowInitGLBindings; 22 } 23 24 namespace cc { 25 class CompletionEvent; 26 class SingleThreadTaskGraphRunner; 27 } 28 namespace chromeos { 29 class BlockingMethodCaller; 30 namespace system { 31 class StatisticsProviderImpl; 32 } 33 } 34 namespace chrome_browser_net { 35 class Predictor; 36 } 37 namespace content { 38 class BrowserGpuChannelHostFactory; 39 class BrowserGpuMemoryBufferManager; 40 class BrowserMainLoop; 41 class BrowserProcessSubThread; 42 class BrowserShutdownProfileDumper; 43 class BrowserTestBase; 44 class CategorizedWorkerPool; 45 class GpuProcessTransportFactory; 46 class NestedMessagePumpAndroid; 47 class ScopedAllowWaitForAndroidLayoutTests; 48 class ScopedAllowWaitForDebugURL; 49 class SessionStorageDatabase; 50 class SoftwareOutputDeviceMus; 51 class ServiceWorkerSubresourceLoader; 52 class SynchronousCompositor; 53 class SynchronousCompositorHost; 54 class SynchronousCompositorSyncCallBridge; 55 class TextInputClientMac; 56 } // namespace content 57 namespace cronet { 58 class CronetPrefsManager; 59 class CronetURLRequestContext; 60 } // namespace cronet 61 namespace dbus { 62 class Bus; 63 } 64 namespace disk_cache { 65 class BackendImpl; 66 class InFlightIO; 67 } 68 namespace functions { 69 class ExecScriptScopedAllowBaseSyncPrimitives; 70 } 71 namespace gpu { 72 class GpuChannelHost; 73 } 74 namespace leveldb { 75 class LevelDBMojoProxy; 76 } 77 namespace media { 78 class AudioInputDevice; 79 class BlockingUrlProtocol; 80 } 81 namespace midi { 82 class TaskService; // https://crbug.com/796830 83 } 84 namespace mojo { 85 class CoreLibraryInitializer; 86 class SyncCallRestrictions; 87 namespace core { 88 class ScopedIPCSupport; 89 } 90 } 91 namespace rlz_lib { 92 class FinancialPing; 93 } 94 namespace ui { 95 class CommandBufferClientImpl; 96 class CommandBufferLocal; 97 class GpuState; 98 class MaterialDesignController; 99 } 100 namespace net { 101 class MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives; 102 class NetworkChangeNotifierMac; 103 namespace internal { 104 class AddressTrackerLinux; 105 } 106 } 107 108 namespace remoting { 109 class AutoThread; 110 } 111 112 namespace resource_coordinator { 113 class TabManagerDelegate; 114 } 115 116 namespace service_manager { 117 class ServiceProcessLauncher; 118 } 119 120 namespace shell_integration { 121 class LaunchXdgUtilityScopedAllowBaseSyncPrimitives; 122 } 123 124 namespace ui { 125 class WindowResizeHelperMac; 126 } 127 128 namespace views { 129 class ScreenMus; 130 } 131 132 namespace viz { 133 class HostGpuMemoryBufferManager; 134 } 135 136 namespace webrtc { 137 class DesktopConfigurationMonitor; 138 } 139 140 namespace base { 141 142 namespace android { 143 class JavaHandlerThread; 144 } 145 146 namespace internal { 147 class TaskTracker; 148 } 149 150 class GetAppOutputScopedAllowBaseSyncPrimitives; 151 class SimpleThread; 152 class StackSamplingProfiler; 153 class Thread; 154 class ThreadTestHelper; 155 156 #if DCHECK_IS_ON() 157 #define INLINE_IF_DCHECK_IS_OFF BASE_EXPORT 158 #define EMPTY_BODY_IF_DCHECK_IS_OFF 159 #else 160 #define INLINE_IF_DCHECK_IS_OFF inline 161 #define EMPTY_BODY_IF_DCHECK_IS_OFF \ 162 {} 163 #endif 164 165 // A "blocking call" refers to any call that causes the calling thread to wait 166 // off-CPU. It includes but is not limited to calls that wait on synchronous 167 // file I/O operations: read or write a file from disk, interact with a pipe or 168 // a socket, rename or delete a file, enumerate files in a directory, etc. 169 // Acquiring a low contention lock is not considered a blocking call. 170 171 // Asserts that blocking calls are allowed in the current scope. 172 // 173 // Style tip: It's best if you put AssertBlockingAllowed() checks as close to 174 // the blocking call as possible. For example: 175 // 176 // void ReadFile() { 177 // PreWork(); 178 // 179 // base::AssertBlockingAllowed(); 180 // fopen(...); 181 // 182 // PostWork(); 183 // } 184 // 185 // void Bar() { 186 // ReadFile(); 187 // } 188 // 189 // void Foo() { 190 // Bar(); 191 // } 192 INLINE_IF_DCHECK_IS_OFF void AssertBlockingAllowed() 193 EMPTY_BODY_IF_DCHECK_IS_OFF; 194 195 // Disallows blocking on the current thread. 196 INLINE_IF_DCHECK_IS_OFF void DisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 197 198 // Disallows blocking calls within its scope. 199 class BASE_EXPORT ScopedDisallowBlocking { 200 public: 201 ScopedDisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 202 ~ScopedDisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 203 204 private: 205 #if DCHECK_IS_ON() 206 const bool was_disallowed_; 207 #endif 208 209 DISALLOW_COPY_AND_ASSIGN(ScopedDisallowBlocking); 210 }; 211 212 // ScopedAllowBlocking(ForTesting) allow blocking calls within a scope where 213 // they are normally disallowed. 214 // 215 // Avoid using this. Prefer making blocking calls from tasks posted to 216 // base::TaskScheduler with base::MayBlock(). 217 // 218 // Where unavoidable, put ScopedAllow* instances in the narrowest scope possible 219 // in the caller making the blocking call but no further down. That is: if a 220 // Cleanup() method needs to do a blocking call, document Cleanup() as blocking 221 // and add a ScopedAllowBlocking instance in callers that can't avoid making 222 // this call from a context where blocking is banned, as such: 223 // void Client::MyMethod() { 224 // (...) 225 // { 226 // // Blocking is okay here because XYZ. 227 // ScopedAllowBlocking allow_blocking; 228 // my_foo_->Cleanup(); 229 // } 230 // (...) 231 // } 232 // 233 // // This method can block. 234 // void Foo::Cleanup() { 235 // // Do NOT add the ScopedAllowBlocking in Cleanup() directly as that hides 236 // // its blocking nature from unknowing callers and defeats the purpose of 237 // // these checks. 238 // FlushStateToDisk(); 239 // } 240 // 241 // Note: In rare situations where the blocking call is an implementation detail 242 // (i.e. the impl makes a call that invokes AssertBlockingAllowed() but it 243 // somehow knows that in practice this will not block), it might be okay to hide 244 // the ScopedAllowBlocking instance in the impl with a comment explaining why 245 // that's okay. 246 class BASE_EXPORT ScopedAllowBlocking { 247 private: 248 // This can only be instantiated by friends. Use ScopedAllowBlockingForTesting 249 // in unit tests to avoid the friend requirement. 250 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, ScopedAllowBlocking); 251 friend class android_webview::ScopedAllowInitGLBindings; 252 friend class content::BrowserProcessSubThread; 253 friend class content::GpuProcessTransportFactory; 254 friend class cronet::CronetPrefsManager; 255 friend class cronet::CronetURLRequestContext; 256 friend class media::AudioInputDevice; 257 friend class mojo::CoreLibraryInitializer; 258 friend class resource_coordinator::TabManagerDelegate; // crbug.com/778703 259 friend class ui::MaterialDesignController; 260 friend class ScopedAllowBlockingForTesting; 261 friend class StackSamplingProfiler; 262 263 ScopedAllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 264 ~ScopedAllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 265 266 #if DCHECK_IS_ON() 267 const bool was_disallowed_; 268 #endif 269 270 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBlocking); 271 }; 272 273 class ScopedAllowBlockingForTesting { 274 public: ScopedAllowBlockingForTesting()275 ScopedAllowBlockingForTesting() {} ~ScopedAllowBlockingForTesting()276 ~ScopedAllowBlockingForTesting() {} 277 278 private: 279 #if DCHECK_IS_ON() 280 ScopedAllowBlocking scoped_allow_blocking_; 281 #endif 282 283 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBlockingForTesting); 284 }; 285 286 // "Waiting on a //base sync primitive" refers to calling one of these methods: 287 // - base::WaitableEvent::*Wait* 288 // - base::ConditionVariable::*Wait* 289 // - base::Process::WaitForExit* 290 291 // Disallows waiting on a //base sync primitive on the current thread. 292 INLINE_IF_DCHECK_IS_OFF void DisallowBaseSyncPrimitives() 293 EMPTY_BODY_IF_DCHECK_IS_OFF; 294 295 // ScopedAllowBaseSyncPrimitives(ForTesting)(OutsideBlockingScope) allow waiting 296 // on a //base sync primitive within a scope where this is normally disallowed. 297 // 298 // Avoid using this. 299 // 300 // Instead of waiting on a WaitableEvent or a ConditionVariable, put the work 301 // that should happen after the wait in a callback and post that callback from 302 // where the WaitableEvent or ConditionVariable would have been signaled. If 303 // something needs to be scheduled after many tasks have executed, use 304 // base::BarrierClosure. 305 // 306 // On Windows, join processes asynchronously using base::win::ObjectWatcher. 307 308 // This can only be used in a scope where blocking is allowed. 309 class BASE_EXPORT ScopedAllowBaseSyncPrimitives { 310 private: 311 // This can only be instantiated by friends. Use 312 // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend 313 // requirement. 314 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 315 ScopedAllowBaseSyncPrimitives); 316 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 317 ScopedAllowBaseSyncPrimitivesResetsState); 318 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 319 ScopedAllowBaseSyncPrimitivesWithBlockingDisallowed); 320 friend class base::GetAppOutputScopedAllowBaseSyncPrimitives; 321 friend class content::BrowserProcessSubThread; 322 friend class content::SessionStorageDatabase; 323 friend class functions::ExecScriptScopedAllowBaseSyncPrimitives; 324 friend class leveldb::LevelDBMojoProxy; 325 friend class media::BlockingUrlProtocol; 326 friend class mojo::core::ScopedIPCSupport; 327 friend class net::MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives; 328 friend class rlz_lib::FinancialPing; 329 friend class shell_integration::LaunchXdgUtilityScopedAllowBaseSyncPrimitives; 330 friend class webrtc::DesktopConfigurationMonitor; 331 friend class content::ServiceWorkerSubresourceLoader; 332 friend class viz::HostGpuMemoryBufferManager; 333 334 ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF; 335 ~ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF; 336 337 #if DCHECK_IS_ON() 338 const bool was_disallowed_; 339 #endif 340 341 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBaseSyncPrimitives); 342 }; 343 344 // This can be used in a scope where blocking is disallowed. 345 class BASE_EXPORT ScopedAllowBaseSyncPrimitivesOutsideBlockingScope { 346 private: 347 // This can only be instantiated by friends. Use 348 // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend 349 // requirement. 350 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 351 ScopedAllowBaseSyncPrimitivesOutsideBlockingScope); 352 FRIEND_TEST_ALL_PREFIXES( 353 ThreadRestrictionsTest, 354 ScopedAllowBaseSyncPrimitivesOutsideBlockingScopeResetsState); 355 friend class ::KeyStorageLinux; 356 friend class content::SynchronousCompositor; 357 friend class content::SynchronousCompositorHost; 358 friend class content::SynchronousCompositorSyncCallBridge; 359 friend class midi::TaskService; // https://crbug.com/796830 360 // Not used in production yet, https://crbug.com/844078. 361 friend class service_manager::ServiceProcessLauncher; 362 363 ScopedAllowBaseSyncPrimitivesOutsideBlockingScope() 364 EMPTY_BODY_IF_DCHECK_IS_OFF; 365 ~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope() 366 EMPTY_BODY_IF_DCHECK_IS_OFF; 367 368 #if DCHECK_IS_ON() 369 const bool was_disallowed_; 370 #endif 371 372 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBaseSyncPrimitivesOutsideBlockingScope); 373 }; 374 375 // This can be used in tests without being a friend of 376 // ScopedAllowBaseSyncPrimitives(OutsideBlockingScope). 377 class BASE_EXPORT ScopedAllowBaseSyncPrimitivesForTesting { 378 public: 379 ScopedAllowBaseSyncPrimitivesForTesting() EMPTY_BODY_IF_DCHECK_IS_OFF; 380 ~ScopedAllowBaseSyncPrimitivesForTesting() EMPTY_BODY_IF_DCHECK_IS_OFF; 381 382 private: 383 #if DCHECK_IS_ON() 384 const bool was_disallowed_; 385 #endif 386 387 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBaseSyncPrimitivesForTesting); 388 }; 389 390 namespace internal { 391 392 // Asserts that waiting on a //base sync primitive is allowed in the current 393 // scope. 394 INLINE_IF_DCHECK_IS_OFF void AssertBaseSyncPrimitivesAllowed() 395 EMPTY_BODY_IF_DCHECK_IS_OFF; 396 397 // Resets all thread restrictions on the current thread. 398 INLINE_IF_DCHECK_IS_OFF void ResetThreadRestrictionsForTesting() 399 EMPTY_BODY_IF_DCHECK_IS_OFF; 400 401 } // namespace internal 402 403 class BASE_EXPORT ThreadRestrictions { 404 public: 405 // Constructing a ScopedAllowIO temporarily allows IO for the current 406 // thread. Doing this is almost certainly always incorrect. 407 // 408 // DEPRECATED. Use ScopedAllowBlocking(ForTesting). 409 class BASE_EXPORT ScopedAllowIO { 410 public: 411 ScopedAllowIO() EMPTY_BODY_IF_DCHECK_IS_OFF; 412 ~ScopedAllowIO() EMPTY_BODY_IF_DCHECK_IS_OFF; 413 414 private: 415 #if DCHECK_IS_ON() 416 const bool was_allowed_; 417 #endif 418 419 DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO); 420 }; 421 422 #if DCHECK_IS_ON() 423 // Set whether the current thread to make IO calls. 424 // Threads start out in the *allowed* state. 425 // Returns the previous value. 426 // 427 // DEPRECATED. Use ScopedAllowBlocking(ForTesting) or ScopedDisallowBlocking. 428 static bool SetIOAllowed(bool allowed); 429 430 // Set whether the current thread can use singletons. Returns the previous 431 // value. 432 static bool SetSingletonAllowed(bool allowed); 433 434 // Check whether the current thread is allowed to use singletons (Singleton / 435 // LazyInstance). DCHECKs if not. 436 static void AssertSingletonAllowed(); 437 438 // Disable waiting on the current thread. Threads start out in the *allowed* 439 // state. Returns the previous value. 440 // 441 // DEPRECATED. Use DisallowBaseSyncPrimitives. 442 static void DisallowWaiting(); 443 #else 444 // Inline the empty definitions of these functions so that they can be 445 // compiled out. SetIOAllowed(bool allowed)446 static bool SetIOAllowed(bool allowed) { return true; } SetSingletonAllowed(bool allowed)447 static bool SetSingletonAllowed(bool allowed) { return true; } AssertSingletonAllowed()448 static void AssertSingletonAllowed() {} DisallowWaiting()449 static void DisallowWaiting() {} 450 #endif 451 452 private: 453 // DO NOT ADD ANY OTHER FRIEND STATEMENTS. 454 // BEGIN ALLOWED USAGE. 455 friend class android_webview::AwFormDatabaseService; 456 friend class android_webview::CookieManager; 457 friend class base::StackSamplingProfiler; 458 friend class content::BrowserMainLoop; 459 friend class content::BrowserShutdownProfileDumper; 460 friend class content::BrowserTestBase; 461 friend class content::NestedMessagePumpAndroid; 462 friend class content::ScopedAllowWaitForAndroidLayoutTests; 463 friend class content::ScopedAllowWaitForDebugURL; 464 friend class ::HistogramSynchronizer; 465 friend class internal::TaskTracker; 466 friend class cc::CompletionEvent; 467 friend class cc::SingleThreadTaskGraphRunner; 468 friend class content::CategorizedWorkerPool; 469 friend class remoting::AutoThread; 470 friend class ui::WindowResizeHelperMac; 471 friend class MessagePumpDefault; 472 friend class SimpleThread; 473 friend class Thread; 474 friend class ThreadTestHelper; 475 friend class PlatformThread; 476 friend class android::JavaHandlerThread; 477 friend class mojo::SyncCallRestrictions; 478 friend class ui::CommandBufferClientImpl; 479 friend class ui::CommandBufferLocal; 480 friend class ui::GpuState; 481 482 // END ALLOWED USAGE. 483 // BEGIN USAGE THAT NEEDS TO BE FIXED. 484 friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360 485 friend class ::chromeos::system::StatisticsProviderImpl; // http://crbug.com/125385 486 friend class chrome_browser_net::Predictor; // http://crbug.com/78451 487 friend class 488 content::BrowserGpuChannelHostFactory; // http://crbug.com/125248 489 friend class 490 content::BrowserGpuMemoryBufferManager; // http://crbug.com/420368 491 friend class content::TextInputClientMac; // http://crbug.com/121917 492 friend class dbus::Bus; // http://crbug.com/125222 493 friend class disk_cache::BackendImpl; // http://crbug.com/74623 494 friend class disk_cache::InFlightIO; // http://crbug.com/74623 495 friend class gpu::GpuChannelHost; // http://crbug.com/125264 496 friend class net::internal::AddressTrackerLinux; // http://crbug.com/125097 497 friend class net::NetworkChangeNotifierMac; // http://crbug.com/125097 498 friend class ::BrowserProcessImpl; // http://crbug.com/125207 499 friend class ::NativeBackendKWallet; // http://crbug.com/125331 500 #if !defined(OFFICIAL_BUILD) 501 friend class content::SoftwareOutputDeviceMus; // Interim non-production code 502 #endif 503 friend class views::ScreenMus; 504 // END USAGE THAT NEEDS TO BE FIXED. 505 506 #if DCHECK_IS_ON() 507 // DEPRECATED. Use ScopedAllowBaseSyncPrimitives. 508 static bool SetWaitAllowed(bool allowed); 509 #else SetWaitAllowed(bool allowed)510 static bool SetWaitAllowed(bool allowed) { return true; } 511 #endif 512 513 // Constructing a ScopedAllowWait temporarily allows waiting on the current 514 // thread. Doing this is almost always incorrect, which is why we limit who 515 // can use this through friend. 516 // 517 // DEPRECATED. Use ScopedAllowBaseSyncPrimitives. 518 class BASE_EXPORT ScopedAllowWait { 519 public: 520 ScopedAllowWait() EMPTY_BODY_IF_DCHECK_IS_OFF; 521 ~ScopedAllowWait() EMPTY_BODY_IF_DCHECK_IS_OFF; 522 523 private: 524 #if DCHECK_IS_ON() 525 const bool was_allowed_; 526 #endif 527 528 DISALLOW_COPY_AND_ASSIGN(ScopedAllowWait); 529 }; 530 531 DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions); 532 }; 533 534 } // namespace base 535 536 #endif // BASE_THREADING_THREAD_RESTRICTIONS_H_ 537