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