1 // Copyright 2012 The Chromium Authors 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/auto_reset.h" 9 #include "base/base_export.h" 10 #include "base/compiler_specific.h" 11 #include "base/dcheck_is_on.h" 12 #include "base/gtest_prod_util.h" 13 #include "base/location.h" 14 #include "build/build_config.h" 15 16 #if DCHECK_IS_ON() 17 #include <optional> 18 19 #include "base/debug/stack_trace.h" 20 #endif 21 22 // ----------------------------------------------------------------------------- 23 // Usage documentation 24 // ----------------------------------------------------------------------------- 25 // 26 // Overview: 27 // This file exposes functions to ban and allow certain slow operations 28 // on a per-thread basis. To annotate *usage* of such slow operations, refer to 29 // scoped_blocking_call.h instead. 30 // 31 // Specific allowances that can be controlled in this file are: 32 // 33 // - Blocking call: Refers to any call that causes the calling thread to wait 34 // off-CPU. It includes but is not limited to calls that wait on synchronous 35 // file I/O operations: read or write a file from disk, interact with a pipe 36 // or a socket, rename or delete a file, enumerate files in a directory, etc. 37 // Acquiring a low contention lock is not considered a blocking call. 38 // 39 // Prefer to allow a blocking call by posting a task to 40 // base::ThreadPoolInstance with base::MayBlock(). 41 // 42 // - Waiting on a //base sync primitive: Refers to calling one of these methods: 43 // - base::WaitableEvent::*Wait* 44 // - base::ConditionVariable::*Wait* 45 // - base::Process::WaitForExit* 46 // 47 // Prefer not to wait on //base sync primitives (see below for alternatives). 48 // When it is unavoidable, use ScopedAllowBaseSyncPrimitives in a task posted 49 // to base::ThreadPoolInstance with base::MayBlock(). 50 // 51 // - Accessing singletons: Accessing global state (Singleton / LazyInstance) is 52 // problematic on threads whom aren't joined on shutdown as they can be using 53 // the state as it becomes invalid during tear down. base::NoDestructor is the 54 // preferred alternative for global state and doesn't have this restriction. 55 // 56 // - Long CPU work: Refers to any code that takes more than 100 ms to 57 // run when there is no CPU contention and no hard page faults and therefore, 58 // is not suitable to run on a thread required to keep the browser responsive 59 // (where jank could be visible to the user). 60 // 61 // The following disallowance functions are offered: 62 // - DisallowBlocking(): Disallows blocking calls on the current thread. 63 // - DisallowBaseSyncPrimitives(): Disallows waiting on a //base sync primitive 64 // on the current thread. 65 // - DisallowSingleton(): Disallows using singletons on the current thread. 66 // - DisallowUnresponsiveTasks(): Disallows blocking calls, waiting on a //base 67 // sync primitive, and long CPU work on the current thread. 68 // 69 // In addition, scoped-allowance mechanisms are offered to make an exception 70 // within a scope for a behavior that is normally disallowed. 71 // - ScopedAllowBlocking: Allows blocking calls. Prefer to use base::MayBlock() 72 // instead. 73 // - ScopedAllowBaseSyncPrimitives: Allows waiting on a //base sync primitive. 74 // Must also be in a scope where blocking calls are allowed. 75 // - ScopedAllowBaseSyncPrimitivesOutsideBlockingScope: Allow waiting on a 76 // //base sync primitive, even in a scope where blocking calls are 77 // disallowed. Prefer to use a combination of base::MayBlock() and 78 // ScopedAllowBaseSyncPrimitives. 79 // 80 // Avoid using allowances outside of unit tests. In unit tests, use allowances 81 // with the suffix "ForTesting": 82 // - ScopedAllowBlockingForTesting: Allows blocking calls in unit tests. 83 // - ScopedAllowBaseSyncPrimitivesForTesting: Allows waiting on a //base sync 84 // primitive in unit tests. For convenience this can be used in a scope 85 // where blocking calls are disallowed. Note that base::TestWaitableEvent can 86 // be used without this, also for convenience. 87 // 88 // Prefer making blocking calls from tasks posted to base::ThreadPoolInstance 89 // with base::MayBlock(). 90 // 91 // Instead of waiting on a WaitableEvent or a ConditionVariable, prefer putting 92 // the work that should happen after the wait in a continuation callback and 93 // post it from where the WaitableEvent or ConditionVariable would have been 94 // signaled. If something needs to be scheduled after many tasks have executed, 95 // use base::BarrierClosure. 96 // 97 // On Windows, join processes asynchronously using base::win::ObjectWatcher. 98 // 99 // Where unavoidable, put ScopedAllow* instances in the narrowest scope possible 100 // in the caller making the blocking call but no further down. For example: if a 101 // Cleanup() method needs to do a blocking call, document Cleanup() as blocking 102 // and add a ScopedAllowBlocking instance in callers that can't avoid making 103 // this call from a context where blocking is banned, as such: 104 // 105 // void Client::MyMethod() { 106 // (...) 107 // { 108 // // Blocking is okay here because XYZ. 109 // ScopedAllowBlocking allow_blocking; 110 // my_foo_->Cleanup(); 111 // } 112 // (...) 113 // } 114 // 115 // // This method can block. 116 // void Foo::Cleanup() { 117 // // Do NOT add the ScopedAllowBlocking in Cleanup() directly as that hides 118 // // its blocking nature from unknowing callers and defeats the purpose of 119 // // these checks. 120 // FlushStateToDisk(); 121 // } 122 // 123 // Note: In rare situations where the blocking call is an implementation detail 124 // (i.e. the impl makes a call that invokes AssertBlockingAllowed() but it 125 // somehow knows that in practice this will not block), it might be okay to hide 126 // the ScopedAllowBlocking instance in the impl with a comment explaining why 127 // that's okay. 128 129 class BrowserProcessImpl; 130 class BrowserThemePack; 131 class ChromeNSSCryptoModuleDelegate; 132 class DesktopNotificationBalloon; 133 class FirefoxProfileLock; 134 class GaiaConfig; 135 class KeyStorageLinux; 136 class NativeBackendKWallet; 137 class NativeDesktopMediaList; 138 class PartnerBookmarksReader; 139 class Profile; 140 class ProfileImpl; 141 class ScopedAllowBlockingForProfile; 142 class StartupTabProviderImpl; 143 class WebEngineBrowserMainParts; 144 145 namespace base { 146 class Environment; 147 class File; 148 class FilePath; 149 namespace sequence_manager::internal { 150 class WorkTracker; 151 } // namespace sequence_manager::internal 152 } // namespace base 153 154 bool EnsureBrowserStateDirectoriesCreated(const base::FilePath&, 155 const base::FilePath&, 156 const base::FilePath&); 157 Profile* GetLastProfileMac(); 158 bool HasWaylandDisplay(base::Environment* env); 159 160 namespace android_webview { 161 class AwBrowserContext; 162 class AwFormDatabaseService; 163 class CookieManager; 164 class JsSandboxIsolate; 165 class ScopedAllowInitGLBindings; 166 class VizCompositorThreadRunnerWebView; 167 } // namespace android_webview 168 namespace ash { 169 class BrowserDataBackMigrator; 170 class LoginEventRecorder; 171 class StartupCustomizationDocument; 172 class StartupUtils; 173 bool CameraAppUIShouldEnableLocalOverride(const std::string&); 174 namespace converters::diagnostics { 175 class MojoUtils; 176 } 177 namespace system { 178 class StatisticsProviderImpl; 179 class ProcStatFile; 180 } // namespace system 181 } // namespace ash 182 namespace audio { 183 class OutputDevice; 184 } 185 namespace blink { 186 class AudioDestination; 187 class DiskDataAllocator; 188 class RTCVideoDecoderAdapter; 189 class RTCVideoEncoder; 190 class SourceStream; 191 class VideoFrameResourceProvider; 192 class WebRtcVideoFrameAdapter; 193 class VideoTrackRecorderImplContextProvider; 194 class WorkerThread; 195 namespace scheduler { 196 class NonMainThreadImpl; 197 } 198 } // namespace blink 199 namespace cc { 200 class CategorizedWorkerPoolImpl; 201 class CategorizedWorkerPoolJob; 202 class CategorizedWorkerPool; 203 class CompletionEvent; 204 class TileTaskManagerImpl; 205 } // namespace cc 206 namespace chrome { 207 bool PathProvider(int, base::FilePath*); 208 void SessionEnding(); 209 } // namespace chrome 210 namespace chromecast { 211 class CrashUtil; 212 } 213 namespace chromeos { 214 class BlockingMethodCaller; 215 namespace system { 216 bool IsCoreSchedulingAvailable(); 217 int NumberOfPhysicalCores(); 218 } // namespace system 219 } // namespace chromeos 220 namespace content { 221 class BrowserGpuChannelHostFactory; 222 class BrowserMainLoop; 223 class BrowserProcessIOThread; 224 class BrowserTestBase; 225 #if BUILDFLAG(IS_IOS) 226 class ContentMainRunnerImpl; 227 #endif // BUILDFLAG(IS_IOS) 228 class DesktopCaptureDevice; 229 class DWriteFontCollectionProxy; 230 class DWriteFontProxyImpl; 231 class EmergencyTraceFinalisationCoordinator; 232 class InProcessUtilityThread; 233 class NestedMessagePumpAndroid; 234 class NetworkServiceInstancePrivate; 235 class PepperPrintSettingsManagerImpl; 236 class RenderProcessHostImpl; 237 class RenderProcessHost; 238 class RenderWidgetHostViewMac; 239 class RendererBlinkPlatformImpl; 240 class SandboxHostLinux; 241 class ScopedAllowWaitForDebugURL; 242 class ServiceWorkerContextClient; 243 class ShellPathProvider; 244 class SynchronousCompositor; 245 class SynchronousCompositorHost; 246 class SynchronousCompositorSyncCallBridge; 247 class ScopedAllowBlockingForViewAura; 248 class TextInputClientMac; 249 class WebContentsImpl; 250 class WebContentsViewMac; 251 base::File CreateFileForDrop(base::FilePath*); 252 } // namespace content 253 namespace cronet { 254 class CronetPrefsManager; 255 class CronetContext; 256 } // namespace cronet 257 namespace crosapi { 258 class LacrosThreadTypeDelegate; 259 } // namespace crosapi 260 namespace crypto { 261 class ScopedAllowBlockingForNSS; 262 } 263 namespace dbus { 264 class Bus; 265 } 266 namespace drive { 267 class FakeDriveService; 268 } 269 namespace device { 270 class UsbContext; 271 } 272 namespace discardable_memory { 273 class ClientDiscardableSharedMemoryManager; 274 } 275 namespace disk_cache { 276 class BackendImpl; 277 class InFlightIO; 278 bool CleanupDirectorySync(const base::FilePath&); 279 } // namespace disk_cache 280 namespace enterprise_connectors { 281 class LinuxKeyRotationCommand; 282 } // namespace enterprise_connectors 283 namespace extensions { 284 class InstalledLoader; 285 class UnpackedInstaller; 286 } // namespace extensions 287 namespace font_service::internal { 288 class MappedFontFile; 289 } 290 namespace gl { 291 struct GLImplementationParts; 292 namespace init { 293 bool InitializeStaticGLBindings(GLImplementationParts); 294 } 295 } // namespace gl 296 namespace history_report { 297 class HistoryReportJniBridge; 298 } 299 namespace ios_web_view { 300 class WebViewBrowserState; 301 } 302 namespace io_thread { 303 class IOSIOThread; 304 } 305 namespace leveldb::port { 306 class CondVar; 307 } // namespace leveldb::port 308 namespace nearby::chrome { 309 class ScheduledExecutor; 310 class SubmittableExecutor; 311 } // namespace nearby::chrome 312 namespace media { 313 class AudioInputDevice; 314 class AudioOutputDevice; 315 class BlockingUrlProtocol; 316 template <class WorkerInterface, 317 class WorkerImpl, 318 class Worker, 319 class WorkerStatus, 320 WorkerStatus StatusNotOk, 321 WorkerStatus StatusOk, 322 WorkerStatus StatusWork> 323 class CodecWorkerImpl; 324 class FileVideoCaptureDeviceFactory; 325 class MojoVideoEncodeAccelerator; 326 class PaintCanvasVideoRenderer; 327 class V4L2DevicePoller; // TODO(1513721): remove this. 328 } // namespace media 329 namespace memory_instrumentation { 330 class OSMetrics; 331 } 332 namespace memory_pressure { 333 class UserLevelMemoryPressureSignalGenerator; 334 } 335 namespace metrics { 336 class AndroidMetricsServiceClient; 337 class CleanExitBeacon; 338 } // namespace metrics 339 namespace midi { 340 class TaskService; // https://crbug.com/796830 341 } 342 namespace module_installer { 343 class ScopedAllowModulePakLoad; 344 } 345 namespace mojo { 346 class CoreLibraryInitializer; 347 class SyncCallRestrictions; 348 namespace core { 349 class ScopedIPCSupport; 350 namespace ipcz_driver { 351 class MojoTrap; 352 } 353 } // namespace core 354 } // namespace mojo 355 namespace net { 356 class GSSAPISharedLibrary; 357 class MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives; 358 class MultiThreadedProxyResolverScopedAllowJoinOnIO; 359 class NetworkChangeNotifierApple; 360 class NetworkConfigWatcherAppleThread; 361 class ProxyConfigServiceWin; 362 class ScopedAllowBlockingForSettingGetter; 363 namespace internal { 364 class AddressTrackerLinux; 365 class PemFileCertStore; 366 } 367 } // namespace net 368 namespace printing { 369 class LocalPrinterHandlerDefault; 370 #if BUILDFLAG(IS_MAC) 371 class PrintBackendServiceImpl; 372 #endif 373 class PrintBackendServiceManager; 374 class PrintPreviewUIUntrusted; 375 class PrinterQuery; 376 } // namespace printing 377 namespace proxy_resolver { 378 class ScopedAllowThreadJoinForProxyResolverV8Tracing; 379 } 380 namespace remote_cocoa { 381 class DroppedScreenShotCopierMac; 382 class SelectFileDialogBridge; 383 } // namespace remote_cocoa 384 namespace remoting { 385 class AutoThread; 386 class ScopedAllowBlockingForCrashReporting; 387 class ScopedBypassIOThreadRestrictions; 388 namespace protocol { 389 class ScopedAllowSyncPrimitivesForWebRtcDataStreamAdapter; 390 class ScopedAllowSyncPrimitivesForWebRtcTransport; 391 class ScopedAllowSyncPrimitivesForWebRtcVideoStream; 392 class ScopedAllowThreadJoinForWebRtcTransport; 393 } // namespace protocol 394 } // namespace remoting 395 namespace rlz_lib { 396 class FinancialPing; 397 } 398 namespace service_manager { 399 class ServiceProcessLauncher; 400 } 401 namespace shell_integration_linux { 402 class LaunchXdgUtilityScopedAllowBaseSyncPrimitives; 403 } 404 namespace storage { 405 class ObfuscatedFileUtil; 406 } 407 namespace syncer { 408 class GetLocalChangesRequest; 409 class HttpBridge; 410 } // namespace syncer 411 namespace tracing { 412 class FuchsiaPerfettoProducerConnector; 413 } 414 namespace ui { 415 class DrmThreadProxy; 416 class DrmDisplayHostManager; 417 class ScopedAllowBlockingForGbmSurface; 418 class SelectFileDialogLinux; 419 class WindowResizeHelperMac; 420 } // namespace ui 421 namespace updater { 422 class SystemctlLauncherScopedAllowBaseSyncPrimitives; 423 } 424 namespace viz { 425 class HostGpuMemoryBufferManager; 426 class ClientGpuMemoryBufferManager; 427 } // namespace viz 428 namespace vr { 429 class VrShell; 430 } 431 namespace web { 432 class WebMainLoop; 433 } // namespace web 434 namespace weblayer { 435 class BrowserContextImpl; 436 class ContentBrowserClientImpl; 437 class ProfileImpl; 438 class WebLayerPathProvider; 439 } // namespace weblayer 440 // NOTE: Please do not append entries here. Put them in the list above and keep 441 // the list sorted. 442 443 namespace base { 444 445 namespace android { 446 class JavaHandlerThread; 447 class PmfUtils; 448 class ScopedAllowBlockingForImportantFileWriter; 449 } // namespace android 450 451 namespace apple::internal { 452 base::FilePath GetExecutablePath(); 453 } 454 455 namespace debug { 456 class StackTrace; 457 } 458 459 namespace internal { 460 class GetAppOutputScopedAllowBaseSyncPrimitives; 461 class JobTaskSource; 462 class TaskTracker; 463 bool ReadProcFile(const FilePath& file, std::string* buffer); 464 } // namespace internal 465 466 namespace sequence_manager::internal { 467 class TaskQueueImpl; 468 } // namespace sequence_manager::internal 469 470 namespace subtle { 471 class PlatformSharedMemoryRegion; 472 } 473 474 namespace win { 475 class OSInfo; 476 class ObjectWatcher; 477 class ScopedAllowBlockingForUserAccountControl; 478 } // namespace win 479 480 class AdjustOOMScoreHelper; 481 class ChromeOSVersionInfo; 482 class FileDescriptorWatcher; 483 class FilePath; 484 class Process; 485 class ScopedAllowBlockingForProc; 486 class ScopedAllowBlockingForProcessMetrics; 487 class ScopedAllowThreadRecallForStackSamplingProfiler; 488 class SimpleThread; 489 class StackSamplingProfiler; 490 class TestCustomDisallow; 491 class Thread; 492 493 #if DCHECK_IS_ON() 494 // NOT_TAIL_CALLED if dcheck-is-on so it's always evident who irrevocably 495 // altered the allowance (dcheck-builds will provide the setter's stack on 496 // assertion) or who made a failing Assert*() call. 497 #define INLINE_OR_NOT_TAIL_CALLED NOT_TAIL_CALLED BASE_EXPORT 498 #define EMPTY_BODY_IF_DCHECK_IS_OFF 499 #define DEFAULT_IF_DCHECK_IS_OFF 500 501 class BooleanWithStack { 502 public: 503 // Default value. 504 BooleanWithStack() = default; 505 506 // Value when explicitly set. 507 explicit BooleanWithStack(bool value); 508 509 explicit operator bool() const { return value_; } 510 511 friend std::ostream& operator<<(std::ostream& out, 512 const BooleanWithStack& bws); 513 514 private: 515 bool value_ = false; 516 std::optional<debug::StackTrace> stack_; 517 }; 518 519 #else 520 // inline if dcheck-is-off so it's no overhead 521 #define INLINE_OR_NOT_TAIL_CALLED inline 522 523 // The static_assert() eats follow-on semicolons. 524 #define EMPTY_BODY_IF_DCHECK_IS_OFF \ 525 {} \ 526 static_assert(true) 527 528 #define DEFAULT_IF_DCHECK_IS_OFF = default 529 #endif // DCHECK_IS_ON() 530 531 namespace internal { 532 533 // Asserts that blocking calls are allowed in the current scope. This is an 534 // internal call, external code should use ScopedBlockingCall instead, which 535 // serves as a precise annotation of the scope that may/will block. 536 INLINE_OR_NOT_TAIL_CALLED void AssertBlockingAllowed() 537 EMPTY_BODY_IF_DCHECK_IS_OFF; 538 INLINE_OR_NOT_TAIL_CALLED void AssertBlockingDisallowedForTesting() 539 EMPTY_BODY_IF_DCHECK_IS_OFF; 540 541 } // namespace internal 542 543 // Disallows blocking on the current thread. 544 INLINE_OR_NOT_TAIL_CALLED void DisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 545 546 // Disallows blocking calls within its scope. 547 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowBlocking { 548 public: 549 ScopedDisallowBlocking() DEFAULT_IF_DCHECK_IS_OFF; 550 551 ScopedDisallowBlocking(const ScopedDisallowBlocking&) = delete; 552 ScopedDisallowBlocking& operator=(const ScopedDisallowBlocking&) = delete; 553 554 ~ScopedDisallowBlocking() DEFAULT_IF_DCHECK_IS_OFF; 555 556 private: 557 #if DCHECK_IS_ON() 558 const AutoReset<BooleanWithStack> resetter_; 559 #endif 560 }; 561 562 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedAllowBlocking { 563 public: 564 ScopedAllowBlocking(const ScopedAllowBlocking&) = delete; 565 ScopedAllowBlocking& operator=(const ScopedAllowBlocking&) = delete; 566 567 private: 568 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 569 NestedAllowRestoresPreviousStack); 570 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, ScopedAllowBlocking); 571 friend class ScopedAllowBlockingForTesting; 572 573 // This can only be instantiated by friends. Use ScopedAllowBlockingForTesting 574 // in unit tests to avoid the friend requirement. 575 // Sorted by class name (with namespace), #if blocks at the bottom. 576 friend class ::BrowserProcessImpl; 577 friend class ::BrowserThemePack; // http://crbug.com/80206 578 friend class ::DesktopNotificationBalloon; 579 friend class ::FirefoxProfileLock; 580 friend class ::GaiaConfig; 581 friend class ::ProfileImpl; 582 friend class ::ScopedAllowBlockingForProfile; 583 friend class ::StartupTabProviderImpl; 584 friend class ::WebEngineBrowserMainParts; 585 friend class android_webview::AwBrowserContext; 586 friend class android_webview::ScopedAllowInitGLBindings; 587 friend class ash::BrowserDataBackMigrator; 588 friend class ash::LoginEventRecorder; 589 friend class ash::StartupCustomizationDocument; // http://crosbug.com/11103 590 friend class ash::StartupUtils; 591 friend class ash::converters::diagnostics::MojoUtils; // http://b/322741627 592 friend class ash::system::ProcStatFile; 593 friend class base::AdjustOOMScoreHelper; 594 friend class base::ChromeOSVersionInfo; 595 friend class base::Process; 596 friend class base::ScopedAllowBlockingForProc; 597 friend class base::ScopedAllowBlockingForProcessMetrics; 598 friend class base::StackSamplingProfiler; 599 friend class base::android::ScopedAllowBlockingForImportantFileWriter; 600 friend class base::android::PmfUtils; 601 friend class base::debug::StackTrace; 602 friend class base::subtle::PlatformSharedMemoryRegion; 603 friend class base::win::ScopedAllowBlockingForUserAccountControl; 604 friend class blink::DiskDataAllocator; 605 friend class chromecast::CrashUtil; 606 friend class content::BrowserProcessIOThread; 607 friend class content::DWriteFontProxyImpl; 608 friend class content::NetworkServiceInstancePrivate; 609 friend class content::PepperPrintSettingsManagerImpl; 610 friend class content::RenderProcessHostImpl; 611 friend class content::RenderWidgetHostViewMac; // http://crbug.com/121917 612 friend class content:: 613 ScopedAllowBlockingForViewAura; // http://crbug.com/332579 614 friend class content::ShellPathProvider; 615 friend class content::WebContentsViewMac; 616 friend class cronet::CronetContext; 617 friend class cronet::CronetPrefsManager; 618 friend class crosapi::LacrosThreadTypeDelegate; 619 friend class crypto::ScopedAllowBlockingForNSS; // http://crbug.com/59847 620 friend class drive::FakeDriveService; 621 friend class extensions::InstalledLoader; 622 friend class extensions::UnpackedInstaller; 623 friend class font_service::internal::MappedFontFile; 624 friend class ios_web_view::WebViewBrowserState; 625 friend class io_thread::IOSIOThread; 626 friend class media::FileVideoCaptureDeviceFactory; 627 friend class memory_instrumentation::OSMetrics; 628 friend class memory_pressure::UserLevelMemoryPressureSignalGenerator; 629 friend class metrics::AndroidMetricsServiceClient; 630 friend class metrics::CleanExitBeacon; 631 friend class module_installer::ScopedAllowModulePakLoad; 632 friend class mojo::CoreLibraryInitializer; 633 friend class net::GSSAPISharedLibrary; // http://crbug.com/66702 634 friend class net::ProxyConfigServiceWin; // http://crbug.com/61453 635 friend class net:: 636 ScopedAllowBlockingForSettingGetter; // http://crbug.com/69057 637 friend class net::internal::PemFileCertStore; 638 friend class printing::LocalPrinterHandlerDefault; 639 friend class printing::PrintBackendServiceManager; 640 friend class printing::PrintPreviewUIUntrusted; 641 friend class printing::PrinterQuery; 642 friend class remote_cocoa:: 643 DroppedScreenShotCopierMac; // https://crbug.com/1148078 644 friend class remote_cocoa::SelectFileDialogBridge; 645 friend class remoting:: 646 ScopedBypassIOThreadRestrictions; // http://crbug.com/1144161 647 friend class remoting::ScopedAllowBlockingForCrashReporting; 648 friend class ui::DrmDisplayHostManager; 649 friend class ui::ScopedAllowBlockingForGbmSurface; 650 friend class ui::SelectFileDialogLinux; 651 friend class weblayer::BrowserContextImpl; 652 friend class weblayer::ContentBrowserClientImpl; 653 friend class weblayer::ProfileImpl; 654 friend class weblayer::WebLayerPathProvider; 655 #if BUILDFLAG(IS_MAC) 656 friend class printing::PrintBackendServiceImpl; 657 #endif 658 #if BUILDFLAG(IS_WIN) 659 friend class base::win::OSInfo; 660 friend class content::WebContentsImpl; // http://crbug.com/1262162 661 #endif 662 663 // Sorted by function name (with namespace), ignoring the return type. 664 friend bool ::EnsureBrowserStateDirectoriesCreated(const base::FilePath&, 665 const base::FilePath&, 666 const base::FilePath&); 667 friend Profile* ::GetLastProfileMac(); // http://crbug.com/1176734 668 friend bool ::HasWaylandDisplay( 669 base::Environment* env); // http://crbug.com/1246928 670 friend bool ash::CameraAppUIShouldEnableLocalOverride(const std::string&); 671 friend base::FilePath base::apple::internal::GetExecutablePath(); 672 friend bool base::internal::ReadProcFile(const FilePath& file, 673 std::string* buffer); 674 friend bool chrome::PathProvider(int, 675 base::FilePath*); // http://crbug.com/259796 676 friend void chrome::SessionEnding(); 677 friend bool chromeos::system::IsCoreSchedulingAvailable(); 678 friend int chromeos::system::NumberOfPhysicalCores(); 679 friend base::File content::CreateFileForDrop( 680 base::FilePath* file_path); // http://crbug.com/110709 681 friend bool disk_cache::CleanupDirectorySync(const base::FilePath&); 682 friend bool gl::init::InitializeStaticGLBindings(gl::GLImplementationParts); 683 684 ScopedAllowBlocking(const Location& from_here = Location::Current()); 685 ~ScopedAllowBlocking(); 686 687 #if DCHECK_IS_ON() 688 const AutoReset<BooleanWithStack> resetter_; 689 #endif 690 }; 691 692 class [[maybe_unused, nodiscard]] ScopedAllowBlockingForTesting { 693 public: 694 ScopedAllowBlockingForTesting() = default; 695 696 ScopedAllowBlockingForTesting(const ScopedAllowBlockingForTesting&) = delete; 697 ScopedAllowBlockingForTesting& operator=( 698 const ScopedAllowBlockingForTesting&) = delete; 699 700 ~ScopedAllowBlockingForTesting() = default; 701 702 private: 703 #if DCHECK_IS_ON() 704 ScopedAllowBlocking scoped_allow_blocking_; 705 #endif 706 }; 707 708 INLINE_OR_NOT_TAIL_CALLED void DisallowBaseSyncPrimitives() 709 EMPTY_BODY_IF_DCHECK_IS_OFF; 710 711 // Disallows singletons within its scope. 712 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowBaseSyncPrimitives { 713 public: 714 ScopedDisallowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF; 715 716 ScopedDisallowBaseSyncPrimitives(const ScopedDisallowBaseSyncPrimitives&) = 717 delete; 718 ScopedDisallowBaseSyncPrimitives& operator=( 719 const ScopedDisallowBaseSyncPrimitives&) = delete; 720 721 ~ScopedDisallowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF; 722 723 private: 724 #if DCHECK_IS_ON() 725 const AutoReset<BooleanWithStack> resetter_; 726 #endif 727 }; 728 729 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedAllowBaseSyncPrimitives { 730 public: 731 ScopedAllowBaseSyncPrimitives(const ScopedAllowBaseSyncPrimitives&) = delete; 732 ScopedAllowBaseSyncPrimitives& operator=( 733 const ScopedAllowBaseSyncPrimitives&) = delete; 734 735 private: 736 // This can only be instantiated by friends. Use 737 // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend 738 // requirement. 739 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 740 ScopedAllowBaseSyncPrimitives); 741 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 742 ScopedAllowBaseSyncPrimitivesResetsState); 743 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 744 ScopedAllowBaseSyncPrimitivesWithBlockingDisallowed); 745 746 // Allowed usage: 747 // Sorted by class name (with namespace). 748 friend class ::ChromeNSSCryptoModuleDelegate; 749 friend class ::PartnerBookmarksReader; 750 friend class ::tracing::FuchsiaPerfettoProducerConnector; 751 friend class android_webview::JsSandboxIsolate; 752 friend class base::SimpleThread; 753 friend class base::internal::GetAppOutputScopedAllowBaseSyncPrimitives; 754 friend class blink::SourceStream; 755 friend class blink::VideoTrackRecorderImplContextProvider; 756 friend class blink::WorkerThread; 757 friend class blink::scheduler::NonMainThreadImpl; 758 friend class cc::CategorizedWorkerPoolImpl; 759 friend class cc::CategorizedWorkerPoolJob; 760 friend class content::BrowserMainLoop; 761 friend class content::BrowserProcessIOThread; 762 friend class content::DWriteFontCollectionProxy; 763 friend class content::RendererBlinkPlatformImpl; 764 friend class content::ServiceWorkerContextClient; 765 friend class device::UsbContext; 766 friend class enterprise_connectors::LinuxKeyRotationCommand; 767 friend class history_report::HistoryReportJniBridge; 768 friend class internal::TaskTracker; 769 friend class leveldb::port::CondVar; 770 friend class nearby::chrome::ScheduledExecutor; 771 friend class nearby::chrome::SubmittableExecutor; 772 friend class media::AudioOutputDevice; 773 friend class media::BlockingUrlProtocol; 774 template <class WorkerInterface, 775 class WorkerImpl, 776 class Worker, 777 class WorkerStatus, 778 WorkerStatus StatusNotOk, 779 WorkerStatus StatusOk, 780 WorkerStatus StatusWork> 781 friend class media::CodecWorkerImpl; 782 friend class media::MojoVideoEncodeAccelerator; 783 friend class mojo::core::ScopedIPCSupport; 784 friend class net::MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives; 785 friend class rlz_lib::FinancialPing; 786 friend class shell_integration_linux:: 787 LaunchXdgUtilityScopedAllowBaseSyncPrimitives; 788 friend class storage::ObfuscatedFileUtil; 789 friend class syncer::HttpBridge; 790 friend class syncer::GetLocalChangesRequest; 791 friend class updater::SystemctlLauncherScopedAllowBaseSyncPrimitives; 792 793 // Usage that should be fixed: 794 // Sorted by class name (with namespace). 795 friend class ::NativeBackendKWallet; // http://crbug.com/125331 796 friend class blink::VideoFrameResourceProvider; // http://crbug.com/878070 797 798 ScopedAllowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF; 799 ~ScopedAllowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF; 800 801 #if DCHECK_IS_ON() 802 const AutoReset<BooleanWithStack> resetter_; 803 #endif 804 }; 805 806 class BASE_EXPORT 807 [[maybe_unused, 808 nodiscard]] ScopedAllowBaseSyncPrimitivesOutsideBlockingScope { 809 public: 810 ScopedAllowBaseSyncPrimitivesOutsideBlockingScope( 811 const ScopedAllowBaseSyncPrimitivesOutsideBlockingScope&) = delete; 812 ScopedAllowBaseSyncPrimitivesOutsideBlockingScope& operator=( 813 const ScopedAllowBaseSyncPrimitivesOutsideBlockingScope&) = delete; 814 815 private: 816 // This can only be instantiated by friends. Use 817 // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend 818 // requirement. 819 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 820 ScopedAllowBaseSyncPrimitivesOutsideBlockingScope); 821 FRIEND_TEST_ALL_PREFIXES( 822 ThreadRestrictionsTest, 823 ScopedAllowBaseSyncPrimitivesOutsideBlockingScopeResetsState); 824 825 // Allowed usage: 826 // Sorted by class name (with namespace). 827 friend class ::BrowserProcessImpl; // http://crbug.com/125207 828 friend class ::KeyStorageLinux; 829 friend class ::NativeDesktopMediaList; 830 friend class android::JavaHandlerThread; 831 friend class android_webview:: 832 AwFormDatabaseService; // http://crbug.com/904431 833 friend class android_webview::CookieManager; 834 friend class android_webview::VizCompositorThreadRunnerWebView; 835 friend class audio::OutputDevice; 836 friend class base::FileDescriptorWatcher; 837 friend class base::ScopedAllowThreadRecallForStackSamplingProfiler; 838 friend class base::StackSamplingProfiler; 839 friend class base::internal::JobTaskSource; 840 friend class base::sequence_manager::internal::TaskQueueImpl; 841 friend class base::sequence_manager::internal::WorkTracker; 842 friend class base::win::ObjectWatcher; 843 friend class blink::AudioDestination; 844 friend class blink::RTCVideoDecoderAdapter; 845 friend class blink::RTCVideoEncoder; 846 friend class blink::WebRtcVideoFrameAdapter; 847 friend class cc::CategorizedWorkerPoolImpl; 848 friend class cc::CategorizedWorkerPoolJob; 849 friend class cc::CategorizedWorkerPool; 850 friend class cc::TileTaskManagerImpl; 851 friend class content::DesktopCaptureDevice; 852 friend class content::EmergencyTraceFinalisationCoordinator; 853 friend class content::InProcessUtilityThread; 854 friend class content::RenderProcessHost; 855 friend class content::SandboxHostLinux; 856 friend class content::ScopedAllowWaitForDebugURL; 857 friend class content::SynchronousCompositor; 858 friend class content::SynchronousCompositorHost; 859 friend class content::SynchronousCompositorSyncCallBridge; 860 friend class media::AudioInputDevice; 861 friend class media::AudioOutputDevice; 862 friend class media::PaintCanvasVideoRenderer; 863 friend class media::V4L2DevicePoller; // TODO(1513721): remove this. 864 friend class mojo::SyncCallRestrictions; 865 friend class mojo::core::ipcz_driver::MojoTrap; 866 friend class net::NetworkConfigWatcherAppleThread; 867 friend class ui::DrmThreadProxy; 868 friend class viz::ClientGpuMemoryBufferManager; 869 friend class viz::HostGpuMemoryBufferManager; 870 friend class vr::VrShell; 871 872 // Usage that should be fixed: 873 friend class ::ash::system::StatisticsProviderImpl; // http://b/261818124 874 friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360 875 friend class base::Thread; // http://crbug.com/918039 876 friend class cc::CompletionEvent; // http://crbug.com/902653 877 friend class content:: 878 BrowserGpuChannelHostFactory; // http://crbug.com/125248 879 friend class content::TextInputClientMac; // http://crbug.com/121917 880 friend class dbus::Bus; // http://crbug.com/125222 881 friend class discardable_memory:: 882 ClientDiscardableSharedMemoryManager; // http://crbug.com/1396355 883 friend class disk_cache::BackendImpl; // http://crbug.com/74623 884 friend class disk_cache::InFlightIO; // http://crbug.com/74623 885 friend class midi::TaskService; // https://crbug.com/796830 886 friend class net:: 887 MultiThreadedProxyResolverScopedAllowJoinOnIO; // http://crbug.com/69710 888 friend class net::NetworkChangeNotifierApple; // http://crbug.com/125097 889 friend class net::internal::AddressTrackerLinux; // http://crbug.com/125097 890 friend class proxy_resolver:: 891 ScopedAllowThreadJoinForProxyResolverV8Tracing; // http://crbug.com/69710 892 friend class remoting::AutoThread; // https://crbug.com/944316 893 friend class remoting::protocol:: 894 ScopedAllowSyncPrimitivesForWebRtcDataStreamAdapter; // http://b/233844893 895 friend class remoting::protocol:: 896 ScopedAllowSyncPrimitivesForWebRtcTransport; // http://crbug.com/1198501 897 friend class remoting::protocol:: 898 ScopedAllowSyncPrimitivesForWebRtcVideoStream; // http://b/304681143 899 friend class remoting::protocol:: 900 ScopedAllowThreadJoinForWebRtcTransport; // http://crbug.com/660081 901 // Not used in production yet, https://crbug.com/844078. 902 friend class service_manager::ServiceProcessLauncher; 903 friend class ui::WindowResizeHelperMac; // http://crbug.com/902829 904 905 ScopedAllowBaseSyncPrimitivesOutsideBlockingScope( 906 const Location& from_here = Location::Current()); 907 908 ~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope(); 909 910 #if DCHECK_IS_ON() 911 const AutoReset<BooleanWithStack> resetter_; 912 #endif 913 }; 914 915 // Allow base-sync-primitives in tests, doesn't require explicit friend'ing like 916 // ScopedAllowBaseSyncPrimitives-types aimed at production do. 917 // Note: For WaitableEvents in the test logic, base::TestWaitableEvent is 918 // exposed as a convenience to avoid the need for 919 // ScopedAllowBaseSyncPrimitivesForTesting. 920 class BASE_EXPORT 921 [[maybe_unused, nodiscard]] ScopedAllowBaseSyncPrimitivesForTesting { 922 public: 923 ScopedAllowBaseSyncPrimitivesForTesting() DEFAULT_IF_DCHECK_IS_OFF; 924 925 ScopedAllowBaseSyncPrimitivesForTesting( 926 const ScopedAllowBaseSyncPrimitivesForTesting&) = delete; 927 ScopedAllowBaseSyncPrimitivesForTesting& operator=( 928 const ScopedAllowBaseSyncPrimitivesForTesting&) = delete; 929 930 ~ScopedAllowBaseSyncPrimitivesForTesting() DEFAULT_IF_DCHECK_IS_OFF; 931 932 private: 933 #if DCHECK_IS_ON() 934 const AutoReset<BooleanWithStack> resetter_; 935 #endif 936 }; 937 938 // Counterpart to base::DisallowUnresponsiveTasks() for tests to allow them to 939 // block their thread after it was banned. 940 class BASE_EXPORT 941 [[maybe_unused, nodiscard]] ScopedAllowUnresponsiveTasksForTesting { 942 public: 943 ScopedAllowUnresponsiveTasksForTesting() DEFAULT_IF_DCHECK_IS_OFF; 944 945 ScopedAllowUnresponsiveTasksForTesting( 946 const ScopedAllowUnresponsiveTasksForTesting&) = delete; 947 ScopedAllowUnresponsiveTasksForTesting& operator=( 948 const ScopedAllowUnresponsiveTasksForTesting&) = delete; 949 950 ~ScopedAllowUnresponsiveTasksForTesting() DEFAULT_IF_DCHECK_IS_OFF; 951 952 private: 953 #if DCHECK_IS_ON() 954 const AutoReset<BooleanWithStack> base_sync_resetter_; 955 const AutoReset<BooleanWithStack> blocking_resetter_; 956 const AutoReset<BooleanWithStack> cpu_resetter_; 957 #endif 958 }; 959 960 namespace internal { 961 962 // Asserts that waiting on a //base sync primitive is allowed in the current 963 // scope. 964 INLINE_OR_NOT_TAIL_CALLED void AssertBaseSyncPrimitivesAllowed() 965 EMPTY_BODY_IF_DCHECK_IS_OFF; 966 967 // Resets all thread restrictions on the current thread. 968 INLINE_OR_NOT_TAIL_CALLED void ResetThreadRestrictionsForTesting() 969 EMPTY_BODY_IF_DCHECK_IS_OFF; 970 971 // Check whether the current thread is allowed to use singletons (Singleton / 972 // LazyInstance). DCHECKs if not. 973 INLINE_OR_NOT_TAIL_CALLED void AssertSingletonAllowed() 974 EMPTY_BODY_IF_DCHECK_IS_OFF; 975 976 } // namespace internal 977 978 // Disallow using singleton on the current thread. 979 INLINE_OR_NOT_TAIL_CALLED void DisallowSingleton() EMPTY_BODY_IF_DCHECK_IS_OFF; 980 981 // Disallows singletons within its scope. 982 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowSingleton { 983 public: 984 ScopedDisallowSingleton() DEFAULT_IF_DCHECK_IS_OFF; 985 986 ScopedDisallowSingleton(const ScopedDisallowSingleton&) = delete; 987 ScopedDisallowSingleton& operator=(const ScopedDisallowSingleton&) = delete; 988 989 ~ScopedDisallowSingleton() DEFAULT_IF_DCHECK_IS_OFF; 990 991 private: 992 #if DCHECK_IS_ON() 993 const AutoReset<BooleanWithStack> resetter_; 994 #endif 995 }; 996 997 // Asserts that running long CPU work is allowed in the current scope. 998 INLINE_OR_NOT_TAIL_CALLED void AssertLongCPUWorkAllowed() 999 EMPTY_BODY_IF_DCHECK_IS_OFF; 1000 1001 INLINE_OR_NOT_TAIL_CALLED void DisallowUnresponsiveTasks() 1002 EMPTY_BODY_IF_DCHECK_IS_OFF; 1003 1004 // Friend-only methods to permanently allow the current thread to use 1005 // blocking/sync-primitives calls. Threads start out in the *allowed* state but 1006 // are typically *disallowed* via the above base::Disallow*() methods after 1007 // being initialized. 1008 // 1009 // Only use these to permanently set the allowance on a thread, e.g. on 1010 // shutdown. For temporary allowances, use scopers above. 1011 class BASE_EXPORT PermanentThreadAllowance { 1012 public: 1013 // Class is merely a namespace-with-friends. 1014 PermanentThreadAllowance() = delete; 1015 1016 private: 1017 // Sorted by class name (with namespace) 1018 friend class base::TestCustomDisallow; 1019 friend class content::BrowserMainLoop; 1020 friend class content::BrowserTestBase; 1021 #if BUILDFLAG(IS_IOS) 1022 friend class content::ContentMainRunnerImpl; 1023 #endif // BUILDFLAG(IS_IOS) 1024 friend class web::WebMainLoop; 1025 1026 static void AllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 1027 static void AllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF; 1028 }; 1029 1030 #undef INLINE_OR_NOT_TAIL_CALLED 1031 #undef EMPTY_BODY_IF_DCHECK_IS_OFF 1032 #undef DEFAULT_IF_DCHECK_IS_OFF 1033 1034 } // namespace base 1035 1036 #endif // BASE_THREADING_THREAD_RESTRICTIONS_H_ 1037