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/check_op.h" 10 #include "base/gtest_prod_util.h" 11 #include "base/location.h" 12 #include "base/macros.h" 13 #include "base/threading/hang_watcher.h" 14 15 // ----------------------------------------------------------------------------- 16 // Usage documentation 17 // ----------------------------------------------------------------------------- 18 // 19 // Overview: 20 // This file exposes functions to ban and allow certain slow operations 21 // on a per-thread basis. To annotate *usage* of such slow operations, refer to 22 // scoped_blocking_call.h instead. 23 // 24 // Specific allowances that can be controlled in this file are: 25 // - Blocking call: Refers to any call that causes the calling thread to wait 26 // off-CPU. It includes but is not limited to calls that wait on synchronous 27 // file I/O operations: read or write a file from disk, interact with a pipe 28 // or a socket, rename or delete a file, enumerate files in a directory, etc. 29 // Acquiring a low contention lock is not considered a blocking call. 30 // 31 // - Waiting on a //base sync primitive: Refers to calling one of these methods: 32 // - base::WaitableEvent::*Wait* 33 // - base::ConditionVariable::*Wait* 34 // - base::Process::WaitForExit* 35 // 36 // - Long CPU work: Refers to any code that takes more than 100 ms to 37 // run when there is no CPU contention and no hard page faults and therefore, 38 // is not suitable to run on a thread required to keep the browser responsive 39 // (where jank could be visible to the user). 40 // 41 // The following disallowance functions are offered: 42 // - DisallowBlocking(): Disallows blocking calls on the current thread. 43 // - DisallowBaseSyncPrimitives(): Disallows waiting on a //base sync primitive 44 // on the current thread. 45 // - DisallowUnresponsiveTasks() Disallows blocking calls, waiting on a //base 46 // sync primitive, and long cpu work on the current thread. 47 // 48 // In addition, scoped-allowance mechanisms are offered to make an exception 49 // within a scope for a behavior that is normally disallowed. 50 // - ScopedAllowBlocking(ForTesting): Allows blocking calls. 51 // - ScopedAllowBaseSyncPrimitives(ForTesting)(OutsideBlockingScope): Allow 52 // waiting on a //base sync primitive. The OutsideBlockingScope suffix allows 53 // uses in a scope where blocking is also disallowed. 54 // 55 // Avoid using allowances outside of unit tests. In unit tests, use allowances 56 // with the suffix "ForTesting". 57 // 58 // Prefer making blocking calls from tasks posted to base::ThreadPoolInstance 59 // with base::MayBlock(). 60 // 61 // Instead of waiting on a WaitableEvent or a ConditionVariable, prefer putting 62 // the work that should happen after the wait in a continuation callback and 63 // post it from where the WaitableEvent or ConditionVariable would have been 64 // signaled. If something needs to be scheduled after many tasks have executed, 65 // use base::BarrierClosure. 66 // 67 // On Windows, join processes asynchronously using base::win::ObjectWatcher. 68 // 69 // Where unavoidable, put ScopedAllow* instances in the narrowest scope possible 70 // in the caller making the blocking call but no further down. For example: if a 71 // Cleanup() method needs to do a blocking call, document Cleanup() as blocking 72 // and add a ScopedAllowBlocking instance in callers that can't avoid making 73 // this call from a context where blocking is banned, as such: 74 // 75 // void Client::MyMethod() { 76 // (...) 77 // { 78 // // Blocking is okay here because XYZ. 79 // ScopedAllowBlocking allow_blocking; 80 // my_foo_->Cleanup(); 81 // } 82 // (...) 83 // } 84 // 85 // // This method can block. 86 // void Foo::Cleanup() { 87 // // Do NOT add the ScopedAllowBlocking in Cleanup() directly as that hides 88 // // its blocking nature from unknowing callers and defeats the purpose of 89 // // these checks. 90 // FlushStateToDisk(); 91 // } 92 // 93 // Note: In rare situations where the blocking call is an implementation detail 94 // (i.e. the impl makes a call that invokes AssertBlockingAllowed() but it 95 // somehow knows that in practice this will not block), it might be okay to hide 96 // the ScopedAllowBlocking instance in the impl with a comment explaining why 97 // that's okay. 98 99 class BrowserProcessImpl; 100 class ChromeNSSCryptoModuleDelegate; 101 class HistogramSynchronizer; 102 class KeyStorageLinux; 103 class NativeBackendKWallet; 104 class NativeDesktopMediaList; 105 106 namespace android_webview { 107 class AwFormDatabaseService; 108 class CookieManager; 109 class ScopedAllowInitGLBindings; 110 class VizCompositorThreadRunnerWebView; 111 } 112 namespace audio { 113 class OutputDevice; 114 } 115 namespace blink { 116 class DiskDataAllocator; 117 class RTCVideoDecoderAdapter; 118 class RTCVideoEncoder; 119 class SourceStream; 120 class VideoFrameResourceProvider; 121 class WorkerThread; 122 namespace scheduler { 123 class WorkerThread; 124 } 125 } 126 namespace cc { 127 class CompletionEvent; 128 class TileTaskManagerImpl; 129 } 130 namespace chromeos { 131 class BlockingMethodCaller; 132 class MojoUtils; 133 namespace system { 134 class StatisticsProviderImpl; 135 } 136 } 137 namespace chrome_browser_net { 138 class Predictor; 139 } 140 namespace chrome_cleaner { 141 class ResetShortcutsComponent; 142 class SystemReportComponent; 143 } 144 namespace content { 145 class BrowserGpuChannelHostFactory; 146 class BrowserMainLoop; 147 class BrowserProcessSubThread; 148 class BrowserShutdownProfileDumper; 149 class BrowserTestBase; 150 class CategorizedWorkerPool; 151 class DesktopCaptureDevice; 152 class InProcessUtilityThread; 153 class NestedMessagePumpAndroid; 154 class NetworkServiceInstancePrivate; 155 class PepperPrintSettingsManagerImpl; 156 class RenderProcessHostImpl; 157 class RenderWidgetHostViewMac; 158 class RTCVideoDecoder; 159 class SandboxHostLinux; 160 class ScopedAllowWaitForDebugURL; 161 class ServiceWorkerContextClient; 162 class SoftwareOutputDeviceMus; 163 class SynchronousCompositor; 164 class SynchronousCompositorHost; 165 class SynchronousCompositorSyncCallBridge; 166 class TextInputClientMac; 167 class WaitForProcessesToDumpProfilingInfo; 168 class WebContentsViewMac; 169 } // namespace content 170 namespace cronet { 171 class CronetPrefsManager; 172 class CronetURLRequestContext; 173 } // namespace cronet 174 namespace dbus { 175 class Bus; 176 } 177 namespace disk_cache { 178 class BackendImpl; 179 class InFlightIO; 180 } 181 namespace functions { 182 class ExecScriptScopedAllowBaseSyncPrimitives; 183 } 184 namespace history_report { 185 class HistoryReportJniBridge; 186 } 187 namespace gpu { 188 class GpuChannelHost; 189 } 190 namespace leveldb_env { 191 class DBTracker; 192 } 193 namespace location { 194 namespace nearby { 195 namespace chrome { 196 class ScheduledExecutor; 197 class SubmittableExecutor; 198 } // namespace chrome 199 } // namespace nearby 200 } // namespace location 201 namespace media { 202 class AudioInputDevice; 203 class AudioOutputDevice; 204 class BlockingUrlProtocol; 205 class PaintCanvasVideoRenderer; 206 } 207 namespace memory_instrumentation { 208 class OSMetrics; 209 } 210 namespace metrics { 211 class AndroidMetricsServiceClient; 212 } 213 namespace midi { 214 class TaskService; // https://crbug.com/796830 215 } 216 namespace module_installer { 217 class ScopedAllowModulePakLoad; 218 } 219 namespace mojo { 220 class CoreLibraryInitializer; 221 class SyncCallRestrictions; 222 namespace core { 223 class ScopedIPCSupport; 224 } 225 } 226 namespace printing { 227 class LocalPrinterHandlerDefault; 228 class PrintJobWorker; 229 class PrinterQuery; 230 } 231 namespace rlz_lib { 232 class FinancialPing; 233 } 234 namespace syncer { 235 class GetLocalChangesRequest; 236 class HttpBridge; 237 } 238 namespace ui { 239 class CommandBufferClientImpl; 240 class CommandBufferLocal; 241 class DrmThreadProxy; 242 class GpuState; 243 } 244 namespace weblayer { 245 class BrowserContextImpl; 246 class ContentBrowserClientImpl; 247 class ProfileImpl; 248 class WebLayerPathProvider; 249 } 250 namespace net { 251 class MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives; 252 class MultiThreadedProxyResolverScopedAllowJoinOnIO; 253 class NetworkChangeNotifierMac; 254 class NetworkConfigWatcherMacThread; 255 namespace internal { 256 class AddressTrackerLinux; 257 } 258 } 259 260 namespace proxy_resolver { 261 class ScopedAllowThreadJoinForProxyResolverV8Tracing; 262 } 263 264 namespace remoting { 265 class AutoThread; 266 namespace protocol { 267 class ScopedAllowThreadJoinForWebRtcTransport; 268 } 269 } 270 271 namespace resource_coordinator { 272 class TabManagerDelegate; 273 } 274 275 namespace service_manager { 276 class ServiceProcessLauncher; 277 } 278 279 namespace shell_integration_linux { 280 class LaunchXdgUtilityScopedAllowBaseSyncPrimitives; 281 } 282 283 namespace ui { 284 class WindowResizeHelperMac; 285 } 286 287 namespace viz { 288 class HostGpuMemoryBufferManager; 289 } 290 291 namespace vr { 292 class VrShell; 293 } 294 295 namespace web { 296 class WebMainLoop; 297 class WebSubThread; 298 } 299 300 namespace webrtc { 301 class DesktopConfigurationMonitor; 302 } 303 304 namespace base { 305 306 namespace sequence_manager { 307 namespace internal { 308 class TaskQueueImpl; 309 } 310 } // namespace sequence_manager 311 312 namespace android { 313 class JavaHandlerThread; 314 } 315 316 namespace internal { 317 class JobTaskSource; 318 class TaskTracker; 319 } 320 321 class AdjustOOMScoreHelper; 322 class FileDescriptorWatcher; 323 class FilePath; 324 class GetAppOutputScopedAllowBaseSyncPrimitives; 325 class ScopedAllowThreadRecallForStackSamplingProfiler; 326 class SimpleThread; 327 class StackSamplingProfiler; 328 class Thread; 329 class WaitableEvent; 330 331 bool PathProviderWin(int, FilePath*); 332 333 #if DCHECK_IS_ON() 334 #define INLINE_IF_DCHECK_IS_OFF BASE_EXPORT 335 #define EMPTY_BODY_IF_DCHECK_IS_OFF 336 #else 337 #define INLINE_IF_DCHECK_IS_OFF inline 338 339 // The static_assert() eats follow-on semicolons. `= default` would work 340 // too, but it makes clang realize that all the Scoped classes are no-ops in 341 // non-dcheck builds and it starts emitting many -Wunused-variable warnings. 342 #define EMPTY_BODY_IF_DCHECK_IS_OFF \ 343 {} \ 344 static_assert(true, "") 345 #endif 346 347 namespace internal { 348 349 // Asserts that blocking calls are allowed in the current scope. This is an 350 // internal call, external code should use ScopedBlockingCall instead, which 351 // serves as a precise annotation of the scope that may/will block. 352 INLINE_IF_DCHECK_IS_OFF void AssertBlockingAllowed() 353 EMPTY_BODY_IF_DCHECK_IS_OFF; 354 355 } // namespace internal 356 357 // Disallows blocking on the current thread. 358 INLINE_IF_DCHECK_IS_OFF void DisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 359 360 // Disallows blocking calls within its scope. 361 class BASE_EXPORT ScopedDisallowBlocking { 362 public: 363 ScopedDisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 364 ~ScopedDisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; 365 366 private: 367 #if DCHECK_IS_ON() 368 const bool was_disallowed_; 369 #endif 370 371 DISALLOW_COPY_AND_ASSIGN(ScopedDisallowBlocking); 372 }; 373 374 class BASE_EXPORT ScopedAllowBlocking { 375 private: 376 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, ScopedAllowBlocking); 377 friend class ScopedAllowBlockingForTesting; 378 379 // This can only be instantiated by friends. Use ScopedAllowBlockingForTesting 380 // in unit tests to avoid the friend requirement. 381 friend class AdjustOOMScoreHelper; 382 friend class StackSamplingProfiler; 383 friend class android_webview::ScopedAllowInitGLBindings; 384 friend class blink::DiskDataAllocator; 385 friend class chromeos::MojoUtils; // http://crbug.com/1055467 386 friend class content::BrowserProcessSubThread; 387 friend class content::NetworkServiceInstancePrivate; 388 friend class content::PepperPrintSettingsManagerImpl; 389 friend class content::RenderProcessHostImpl; 390 friend class content::RenderWidgetHostViewMac; // http://crbug.com/121917 391 friend class content::WebContentsViewMac; 392 friend class cronet::CronetPrefsManager; 393 friend class cronet::CronetURLRequestContext; 394 friend class memory_instrumentation::OSMetrics; 395 friend class metrics::AndroidMetricsServiceClient; 396 friend class module_installer::ScopedAllowModulePakLoad; 397 friend class mojo::CoreLibraryInitializer; 398 friend class printing::LocalPrinterHandlerDefault; 399 friend class printing::PrintJobWorker; 400 friend class resource_coordinator::TabManagerDelegate; // crbug.com/778703 401 friend class web::WebSubThread; 402 friend class weblayer::BrowserContextImpl; 403 friend class weblayer::ContentBrowserClientImpl; 404 friend class weblayer::ProfileImpl; 405 friend class weblayer::WebLayerPathProvider; 406 407 friend bool PathProviderWin(int, FilePath*); 408 409 ScopedAllowBlocking(const Location& from_here = Location::Current()); 410 ~ScopedAllowBlocking(); 411 412 #if DCHECK_IS_ON() 413 const bool was_disallowed_; 414 #endif 415 416 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBlocking); 417 }; 418 419 class ScopedAllowBlockingForTesting { 420 public: ScopedAllowBlockingForTesting()421 ScopedAllowBlockingForTesting() {} ~ScopedAllowBlockingForTesting()422 ~ScopedAllowBlockingForTesting() {} 423 424 private: 425 #if DCHECK_IS_ON() 426 ScopedAllowBlocking scoped_allow_blocking_; 427 #endif 428 429 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBlockingForTesting); 430 }; 431 432 INLINE_IF_DCHECK_IS_OFF void DisallowBaseSyncPrimitives() 433 EMPTY_BODY_IF_DCHECK_IS_OFF; 434 435 class BASE_EXPORT ScopedAllowBaseSyncPrimitives { 436 private: 437 // This can only be instantiated by friends. Use 438 // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend 439 // requirement. 440 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 441 ScopedAllowBaseSyncPrimitives); 442 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 443 ScopedAllowBaseSyncPrimitivesResetsState); 444 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 445 ScopedAllowBaseSyncPrimitivesWithBlockingDisallowed); 446 447 // Allowed usage: 448 friend class SimpleThread; 449 friend class ::ChromeNSSCryptoModuleDelegate; 450 friend class base::GetAppOutputScopedAllowBaseSyncPrimitives; 451 friend class blink::SourceStream; 452 friend class blink::WorkerThread; 453 friend class blink::scheduler::WorkerThread; 454 friend class chrome_cleaner::ResetShortcutsComponent; 455 friend class chrome_cleaner::SystemReportComponent; 456 friend class content::BrowserMainLoop; 457 friend class content::BrowserProcessSubThread; 458 friend class content::ServiceWorkerContextClient; 459 friend class functions::ExecScriptScopedAllowBaseSyncPrimitives; 460 friend class history_report::HistoryReportJniBridge; 461 friend class internal::TaskTracker; 462 friend class leveldb_env::DBTracker; 463 friend class location::nearby::chrome::ScheduledExecutor; 464 friend class location::nearby::chrome::SubmittableExecutor; 465 friend class media::BlockingUrlProtocol; 466 friend class mojo::core::ScopedIPCSupport; 467 friend class net::MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives; 468 friend class rlz_lib::FinancialPing; 469 friend class shell_integration_linux:: 470 LaunchXdgUtilityScopedAllowBaseSyncPrimitives; 471 friend class syncer::HttpBridge; 472 friend class syncer::GetLocalChangesRequest; 473 friend class webrtc::DesktopConfigurationMonitor; 474 475 // Usage that should be fixed: 476 friend class ::NativeBackendKWallet; // http://crbug.com/125331 477 friend class ::chromeos::system:: 478 StatisticsProviderImpl; // http://crbug.com/125385 479 friend class blink::VideoFrameResourceProvider; // http://crbug.com/878070 480 481 ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF; 482 ~ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF; 483 484 #if DCHECK_IS_ON() 485 const bool was_disallowed_; 486 #endif 487 488 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBaseSyncPrimitives); 489 }; 490 491 class BASE_EXPORT ScopedAllowBaseSyncPrimitivesOutsideBlockingScope { 492 private: 493 // This can only be instantiated by friends. Use 494 // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend 495 // requirement. 496 FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, 497 ScopedAllowBaseSyncPrimitivesOutsideBlockingScope); 498 FRIEND_TEST_ALL_PREFIXES( 499 ThreadRestrictionsTest, 500 ScopedAllowBaseSyncPrimitivesOutsideBlockingScopeResetsState); 501 502 // Allowed usage: 503 friend class ::BrowserProcessImpl; // http://crbug.com/125207 504 friend class ::KeyStorageLinux; 505 friend class ::NativeDesktopMediaList; 506 friend class android::JavaHandlerThread; 507 friend class android_webview:: 508 AwFormDatabaseService; // http://crbug.com/904431 509 friend class android_webview::CookieManager; 510 friend class android_webview::VizCompositorThreadRunnerWebView; 511 friend class audio::OutputDevice; 512 friend class base::sequence_manager::internal::TaskQueueImpl; 513 friend class base::FileDescriptorWatcher; 514 friend class base::internal::JobTaskSource; 515 friend class base::ScopedAllowThreadRecallForStackSamplingProfiler; 516 friend class base::StackSamplingProfiler; 517 friend class blink::RTCVideoDecoderAdapter; 518 friend class blink::RTCVideoEncoder; 519 friend class cc::TileTaskManagerImpl; 520 friend class content::CategorizedWorkerPool; 521 friend class content::DesktopCaptureDevice; 522 friend class content::InProcessUtilityThread; 523 friend class content::RTCVideoDecoder; 524 friend class content::SandboxHostLinux; 525 friend class content::ScopedAllowWaitForDebugURL; 526 friend class content::SynchronousCompositor; 527 friend class content::SynchronousCompositorHost; 528 friend class content::SynchronousCompositorSyncCallBridge; 529 friend class content::WaitForProcessesToDumpProfilingInfo; 530 friend class media::AudioInputDevice; 531 friend class media::AudioOutputDevice; 532 friend class media::PaintCanvasVideoRenderer; 533 friend class mojo::SyncCallRestrictions; 534 friend class net::NetworkConfigWatcherMacThread; 535 friend class ui::DrmThreadProxy; 536 friend class viz::HostGpuMemoryBufferManager; 537 friend class vr::VrShell; 538 539 // Usage that should be fixed: 540 friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360 541 friend class base::Thread; // http://crbug.com/918039 542 friend class cc::CompletionEvent; // http://crbug.com/902653 543 friend class content:: 544 BrowserGpuChannelHostFactory; // http://crbug.com/125248 545 friend class dbus::Bus; // http://crbug.com/125222 546 friend class disk_cache::BackendImpl; // http://crbug.com/74623 547 friend class disk_cache::InFlightIO; // http://crbug.com/74623 548 friend class gpu::GpuChannelHost; // http://crbug.com/125264 549 friend class remoting::protocol:: 550 ScopedAllowThreadJoinForWebRtcTransport; // http://crbug.com/660081 551 friend class midi::TaskService; // https://crbug.com/796830 552 friend class net::internal::AddressTrackerLinux; // http://crbug.com/125097 553 friend class net:: 554 MultiThreadedProxyResolverScopedAllowJoinOnIO; // http://crbug.com/69710 555 friend class net::NetworkChangeNotifierMac; // http://crbug.com/125097 556 friend class printing::PrinterQuery; // http://crbug.com/66082 557 friend class proxy_resolver:: 558 ScopedAllowThreadJoinForProxyResolverV8Tracing; // http://crbug.com/69710 559 friend class remoting::AutoThread; // https://crbug.com/944316 560 // Not used in production yet, https://crbug.com/844078. 561 friend class service_manager::ServiceProcessLauncher; 562 friend class ui::WindowResizeHelperMac; // http://crbug.com/902829 563 friend class content::TextInputClientMac; // http://crbug.com/121917 564 565 ScopedAllowBaseSyncPrimitivesOutsideBlockingScope( 566 const Location& from_here = Location::Current()); 567 568 ~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope(); 569 570 #if DCHECK_IS_ON() 571 const bool was_disallowed_; 572 #endif 573 574 // Since this object is used to indicate that sync primitives will be used to 575 // wait for an event ignore the current operation for hang watching purposes 576 // since the wait time duration is unknown. 577 base::HangWatchScopeDisabled hang_watch_scope_disabled_; 578 579 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBaseSyncPrimitivesOutsideBlockingScope); 580 }; 581 582 // Allow base-sync-primitives in tests, doesn't require explicit friend'ing like 583 // ScopedAllowBaseSyncPrimitives-types aimed at production do. 584 // Note: For WaitableEvents in the test logic, base::TestWaitableEvent is 585 // exposed as a convenience to avoid the need for 586 // ScopedAllowBaseSyncPrimitivesForTesting. 587 class BASE_EXPORT ScopedAllowBaseSyncPrimitivesForTesting { 588 public: 589 ScopedAllowBaseSyncPrimitivesForTesting() EMPTY_BODY_IF_DCHECK_IS_OFF; 590 ~ScopedAllowBaseSyncPrimitivesForTesting() EMPTY_BODY_IF_DCHECK_IS_OFF; 591 592 private: 593 #if DCHECK_IS_ON() 594 const bool was_disallowed_; 595 #endif 596 597 DISALLOW_COPY_AND_ASSIGN(ScopedAllowBaseSyncPrimitivesForTesting); 598 }; 599 600 // Counterpart to base::DisallowUnresponsiveTasks() for tests to allow them to 601 // block their thread after it was banned. 602 class BASE_EXPORT ScopedAllowUnresponsiveTasksForTesting { 603 public: 604 ScopedAllowUnresponsiveTasksForTesting() EMPTY_BODY_IF_DCHECK_IS_OFF; 605 ~ScopedAllowUnresponsiveTasksForTesting() EMPTY_BODY_IF_DCHECK_IS_OFF; 606 607 private: 608 #if DCHECK_IS_ON() 609 const bool was_disallowed_base_sync_; 610 const bool was_disallowed_blocking_; 611 const bool was_disallowed_cpu_; 612 #endif 613 614 DISALLOW_COPY_AND_ASSIGN(ScopedAllowUnresponsiveTasksForTesting); 615 }; 616 617 namespace internal { 618 619 // Asserts that waiting on a //base sync primitive is allowed in the current 620 // scope. 621 INLINE_IF_DCHECK_IS_OFF void AssertBaseSyncPrimitivesAllowed() 622 EMPTY_BODY_IF_DCHECK_IS_OFF; 623 624 // Resets all thread restrictions on the current thread. 625 INLINE_IF_DCHECK_IS_OFF void ResetThreadRestrictionsForTesting() 626 EMPTY_BODY_IF_DCHECK_IS_OFF; 627 628 } // namespace internal 629 630 // Asserts that running long CPU work is allowed in the current scope. 631 INLINE_IF_DCHECK_IS_OFF void AssertLongCPUWorkAllowed() 632 EMPTY_BODY_IF_DCHECK_IS_OFF; 633 634 INLINE_IF_DCHECK_IS_OFF void DisallowUnresponsiveTasks() 635 EMPTY_BODY_IF_DCHECK_IS_OFF; 636 637 class BASE_EXPORT ThreadRestrictions { 638 public: 639 // Constructing a ScopedAllowIO temporarily allows IO for the current 640 // thread. Doing this is almost certainly always incorrect. 641 // 642 // DEPRECATED. Use ScopedAllowBlocking(ForTesting). 643 class BASE_EXPORT ScopedAllowIO { 644 public: 645 ScopedAllowIO(const Location& from_here = Location::Current()); 646 ~ScopedAllowIO(); 647 648 private: 649 #if DCHECK_IS_ON() 650 const bool was_allowed_; 651 #endif 652 653 DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO); 654 }; 655 656 #if DCHECK_IS_ON() 657 // Set whether the current thread to make IO calls. 658 // Threads start out in the *allowed* state. 659 // Returns the previous value. 660 // 661 // DEPRECATED. Use ScopedAllowBlocking(ForTesting) or ScopedDisallowBlocking. 662 static bool SetIOAllowed(bool allowed); 663 664 // Set whether the current thread can use singletons. Returns the previous 665 // value. 666 static bool SetSingletonAllowed(bool allowed); 667 668 // Check whether the current thread is allowed to use singletons (Singleton / 669 // LazyInstance). DCHECKs if not. 670 static void AssertSingletonAllowed(); 671 672 // Disable waiting on the current thread. Threads start out in the *allowed* 673 // state. Returns the previous value. 674 // 675 // DEPRECATED. Use DisallowBaseSyncPrimitives. 676 static void DisallowWaiting(); 677 #else 678 // Inline the empty definitions of these functions so that they can be 679 // compiled out. SetIOAllowed(bool allowed)680 static bool SetIOAllowed(bool allowed) { return true; } SetSingletonAllowed(bool allowed)681 static bool SetSingletonAllowed(bool allowed) { return true; } AssertSingletonAllowed()682 static void AssertSingletonAllowed() {} DisallowWaiting()683 static void DisallowWaiting() {} 684 #endif 685 686 private: 687 // DO NOT ADD ANY OTHER FRIEND STATEMENTS. 688 // BEGIN ALLOWED USAGE. 689 friend class content::BrowserMainLoop; 690 friend class content::BrowserShutdownProfileDumper; 691 friend class content::BrowserTestBase; 692 friend class content::ScopedAllowWaitForDebugURL; 693 friend class ::HistogramSynchronizer; 694 friend class internal::TaskTracker; 695 friend class web::WebMainLoop; 696 friend class MessagePumpDefault; 697 friend class PlatformThread; 698 friend class ui::CommandBufferClientImpl; 699 friend class ui::CommandBufferLocal; 700 friend class ui::GpuState; 701 702 // END ALLOWED USAGE. 703 // BEGIN USAGE THAT NEEDS TO BE FIXED. 704 friend class chrome_browser_net::Predictor; // http://crbug.com/78451 705 #if !defined(OFFICIAL_BUILD) 706 friend class content::SoftwareOutputDeviceMus; // Interim non-production code 707 #endif 708 // END USAGE THAT NEEDS TO BE FIXED. 709 710 #if DCHECK_IS_ON() 711 // DEPRECATED. Use ScopedAllowBaseSyncPrimitives. 712 static bool SetWaitAllowed(bool allowed); 713 #else SetWaitAllowed(bool allowed)714 static bool SetWaitAllowed(bool allowed) { return true; } 715 #endif 716 717 DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions); 718 }; 719 720 #undef INLINE_IF_DCHECK_IS_OFF 721 #undef EMPTY_BODY_IF_DCHECK_IS_OFF 722 723 } // namespace base 724 725 #endif // BASE_THREADING_THREAD_RESTRICTIONS_H_ 726