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