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