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