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