thread_restrictions.h 23 KB

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