• 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 KeyStorageLinux;
134 class NativeBackendKWallet;
135 class NativeDesktopMediaList;
136 class Profile;
137 class ProfileImpl;
138 class StartupTabProviderImpl;
139 class GaiaConfig;
140 class WebEngineBrowserMainParts;
141 class ScopedAllowBlockingForProfile;
142 
143 namespace base {
144 class File;
145 class FilePath;
146 }  // namespace base
147 
148 Profile* GetLastProfileMac();
149 bool EnsureBrowserStateDirectoriesCreated(const base::FilePath&,
150                                           const base::FilePath&,
151                                           const base::FilePath&);
152 
153 namespace android_webview {
154 class AwFormDatabaseService;
155 class CookieManager;
156 class JsSandboxIsolate;
157 class ScopedAllowInitGLBindings;
158 class VizCompositorThreadRunnerWebView;
159 }  // namespace android_webview
160 namespace ash {
161 class MojoUtils;
162 class BrowserDataBackMigrator;
163 class LoginEventRecorder;
164 class StartupCustomizationDocument;
165 class StartupUtils;
166 bool CameraAppUIShouldEnableLocalOverride(const std::string&);
167 namespace system {
168 class StatisticsProviderImpl;
169 }  // namespace system
170 }  // namespace ash
171 namespace audio {
172 class OutputDevice;
173 }
174 namespace blink {
175 class DiskDataAllocator;
176 class IdentifiabilityActiveSampler;
177 class RTCVideoDecoderAdapter;
178 class RTCVideoEncoder;
179 class SourceStream;
180 class VideoFrameResourceProvider;
181 class WebRtcVideoFrameAdapter;
182 class LegacyWebRtcVideoFrameAdapter;
183 class VideoTrackRecorderImplContextProvider;
184 class WorkerThread;
185 namespace scheduler {
186 class NonMainThreadImpl;
187 }
188 }  // namespace blink
189 namespace cc {
190 class CategorizedWorkerPoolImpl;
191 class CategorizedWorkerPoolJob;
192 class CategorizedWorkerPool;
193 class CompletionEvent;
194 class TileTaskManagerImpl;
195 }  // namespace cc
196 namespace chrome {
197 bool PathProvider(int, base::FilePath*);
198 void SessionEnding();
199 }  // namespace chrome
200 namespace chromecast {
201 class CrashUtil;
202 }
203 namespace chromeos {
204 class BlockingMethodCaller;
205 namespace system {
206 bool IsCoreSchedulingAvailable();
207 int NumberOfPhysicalCores();
208 }  // namespace system
209 }  // namespace chromeos
210 namespace chrome_cleaner {
211 class ResetShortcutsComponent;
212 class SystemReportComponent;
213 }  // namespace chrome_cleaner
214 namespace content {
215 class BrowserGpuChannelHostFactory;
216 class BrowserMainLoop;
217 class BrowserProcessIOThread;
218 class BrowserTestBase;
219 #if BUILDFLAG(IS_IOS)
220 class ContentMainRunnerImpl;
221 #endif  // BUILDFLAG(IS_IOS)
222 class DesktopCaptureDevice;
223 class DWriteFontCollectionProxy;
224 class DWriteFontProxyImpl;
225 class EmergencyTraceFinalisationCoordinator;
226 class InProcessUtilityThread;
227 class NestedMessagePumpAndroid;
228 class NetworkServiceInstancePrivate;
229 class PepperPrintSettingsManagerImpl;
230 class RenderProcessHostImpl;
231 class RenderProcessHost;
232 class RenderWidgetHostViewMac;
233 class RendererBlinkPlatformImpl;
234 class RTCVideoDecoder;
235 class SandboxHostLinux;
236 class ScopedAllowWaitForDebugURL;
237 class ServiceWorkerContextClient;
238 class ShellPathProvider;
239 class SynchronousCompositor;
240 class SynchronousCompositorHost;
241 class SynchronousCompositorSyncCallBridge;
242 class ScopedAllowBlockingForViewAura;
243 class TextInputClientMac;
244 class WebContentsImpl;
245 class WebContentsViewMac;
246 base::File CreateFileForDrop(base::FilePath*);
247 }  // namespace content
248 namespace cronet {
249 class CronetPrefsManager;
250 class CronetContext;
251 }  // namespace cronet
252 namespace crosapi {
253 class LacrosThreadTypeDelegate;
254 }  // namespace crosapi
255 namespace crypto {
256 class ScopedAllowBlockingForNSS;
257 }
258 namespace dbus {
259 class Bus;
260 }
261 namespace drive {
262 class FakeDriveService;
263 }
264 namespace device {
265 class UsbContext;
266 }
267 namespace discardable_memory {
268 class ClientDiscardableSharedMemoryManager;
269 }
270 namespace disk_cache {
271 class BackendImpl;
272 class InFlightIO;
273 bool CleanupDirectorySync(const base::FilePath&);
274 }  // namespace disk_cache
275 namespace enterprise_connectors {
276 class LinuxKeyRotationCommand;
277 }  // namespace enterprise_connectors
278 namespace extensions {
279 class InstalledLoader;
280 class UnpackedInstaller;
281 }  // namespace extensions
282 namespace font_service::internal {
283 class MappedFontFile;
284 }
285 namespace functions {
286 class ExecScriptScopedAllowBaseSyncPrimitives;
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 printing {
345 class LocalPrinterHandlerDefault;
346 #if BUILDFLAG(IS_MAC)
347 class PrintBackendServiceImpl;
348 #endif
349 class PrintBackendServiceManager;
350 class PrinterQuery;
351 }  // namespace printing
352 namespace rlz_lib {
353 class FinancialPing;
354 }
355 namespace storage {
356 class ObfuscatedFileUtil;
357 }
358 namespace syncer {
359 class GetLocalChangesRequest;
360 class HttpBridge;
361 }  // namespace syncer
362 namespace ui {
363 class DrmThreadProxy;
364 class DrmDisplayHostManager;
365 class SelectFileDialogLinux;
366 class ScopedAllowBlockingForGbmSurface;
367 }  // namespace ui
368 namespace weblayer {
369 class BrowserContextImpl;
370 class ContentBrowserClientImpl;
371 class ProfileImpl;
372 class WebLayerPathProvider;
373 }  // namespace weblayer
374 namespace net {
375 class GSSAPISharedLibrary;
376 class MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives;
377 class MultiThreadedProxyResolverScopedAllowJoinOnIO;
378 class NetworkChangeNotifierMac;
379 class NetworkConfigWatcherMacThread;
380 class ProxyConfigServiceWin;
381 class ScopedAllowBlockingForSettingGetter;
382 namespace internal {
383 class AddressTrackerLinux;
384 }
385 }  // namespace net
386 
387 namespace proxy_resolver {
388 class ScopedAllowThreadJoinForProxyResolverV8Tracing;
389 }
390 
391 namespace remote_cocoa {
392 class DroppedScreenShotCopierMac;
393 class SelectFileDialogBridge;
394 }  // namespace remote_cocoa
395 
396 namespace remoting {
397 class AutoThread;
398 class ScopedBypassIOThreadRestrictions;
399 namespace protocol {
400 class ScopedAllowSyncPrimitivesForWebRtcDataStreamAdapter;
401 class ScopedAllowSyncPrimitivesForWebRtcTransport;
402 class ScopedAllowThreadJoinForWebRtcTransport;
403 }  // namespace protocol
404 }  // namespace remoting
405 
406 namespace service_manager {
407 class ServiceProcessLauncher;
408 }
409 
410 namespace shell_integration_linux {
411 class LaunchXdgUtilityScopedAllowBaseSyncPrimitives;
412 }
413 
414 namespace tracing {
415 class FuchsiaPerfettoProducerConnector;
416 }
417 
418 namespace ui {
419 class WindowResizeHelperMac;
420 }
421 
422 namespace updater {
423 class SystemctlLauncherScopedAllowBaseSyncPrimitives;
424 }
425 
426 namespace viz {
427 class HostGpuMemoryBufferManager;
428 class ClientGpuMemoryBufferManager;
429 }  // namespace viz
430 
431 namespace vr {
432 class VrShell;
433 }
434 
435 namespace web {
436 class WebMainLoop;
437 }  // namespace web
438 
439 namespace webrtc {
440 class DesktopConfigurationMonitor;
441 }
442 
443 namespace base {
444 class Environment;
445 }
446 
447 bool HasWaylandDisplay(base::Environment* env);
448 
449 namespace base {
450 
451 namespace sequence_manager::internal {
452 class TaskQueueImpl;
453 }  // namespace sequence_manager::internal
454 
455 namespace android {
456 class JavaHandlerThread;
457 class ScopedAllowBlockingForImportantFileWriter;
458 }  // namespace android
459 
460 namespace internal {
461 class GetAppOutputScopedAllowBaseSyncPrimitives;
462 class JobTaskSource;
463 class TaskTracker;
464 bool ReadProcFile(const FilePath& file, std::string* buffer);
465 }  // namespace internal
466 
467 namespace subtle {
468 class PlatformSharedMemoryRegion;
469 }
470 
471 namespace debug {
472 class StackTrace;
473 }
474 
475 namespace win {
476 class OSInfo;
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 void GetNSExecutablePath(base::FilePath* path);
494 
495 #if DCHECK_IS_ON()
496 // NOT_TAIL_CALLED if dcheck-is-on so it's always evident who irrevocably
497 // altered the allowance (dcheck-builds will provide the setter's stack on
498 // assertion) or who made a failing Assert*() call.
499 #define INLINE_OR_NOT_TAIL_CALLED NOT_TAIL_CALLED BASE_EXPORT
500 #define EMPTY_BODY_IF_DCHECK_IS_OFF
501 #define DEFAULT_IF_DCHECK_IS_OFF
502 
503 class BooleanWithStack {
504  public:
505   // Default value.
506   BooleanWithStack() = default;
507 
508   // Value when explicitly set.
509   explicit BooleanWithStack(bool value);
510 
511   explicit operator bool() const { return value_; }
512 
513   friend std::ostream& operator<<(std::ostream& out,
514                                   const BooleanWithStack& bws);
515 
516  private:
517   bool value_ = false;
518   absl::optional<debug::StackTrace> stack_;
519 };
520 
521 #else
522 // inline if dcheck-is-off so it's no overhead
523 #define INLINE_OR_NOT_TAIL_CALLED inline
524 
525 // The static_assert() eats follow-on semicolons.
526 #define EMPTY_BODY_IF_DCHECK_IS_OFF \
527   {}                                \
528   static_assert(true)
529 
530 #define DEFAULT_IF_DCHECK_IS_OFF = default
531 #endif  // DCHECK_IS_ON()
532 
533 namespace internal {
534 
535 // Asserts that blocking calls are allowed in the current scope. This is an
536 // internal call, external code should use ScopedBlockingCall instead, which
537 // serves as a precise annotation of the scope that may/will block.
538 INLINE_OR_NOT_TAIL_CALLED void AssertBlockingAllowed()
539     EMPTY_BODY_IF_DCHECK_IS_OFF;
540 INLINE_OR_NOT_TAIL_CALLED void AssertBlockingDisallowedForTesting()
541     EMPTY_BODY_IF_DCHECK_IS_OFF;
542 
543 }  // namespace internal
544 
545 // Disallows blocking on the current thread.
546 INLINE_OR_NOT_TAIL_CALLED void DisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
547 
548 // Disallows blocking calls within its scope.
549 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowBlocking {
550  public:
551   ScopedDisallowBlocking() DEFAULT_IF_DCHECK_IS_OFF;
552 
553   ScopedDisallowBlocking(const ScopedDisallowBlocking&) = delete;
554   ScopedDisallowBlocking& operator=(const ScopedDisallowBlocking&) = delete;
555 
556   ~ScopedDisallowBlocking() DEFAULT_IF_DCHECK_IS_OFF;
557 
558  private:
559 #if DCHECK_IS_ON()
560   const AutoReset<BooleanWithStack> resetter_;
561 #endif
562 };
563 
564 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedAllowBlocking {
565  public:
566   ScopedAllowBlocking(const ScopedAllowBlocking&) = delete;
567   ScopedAllowBlocking& operator=(const ScopedAllowBlocking&) = delete;
568 
569  private:
570   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest,
571                            NestedAllowRestoresPreviousStack);
572   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, ScopedAllowBlocking);
573   friend class ScopedAllowBlockingForTesting;
574 
575   // This can only be instantiated by friends. Use ScopedAllowBlockingForTesting
576   // in unit tests to avoid the friend requirement.
577   // Sorted by class name (with namespace), #if blocks at the bottom.
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::ScopedAllowInitGLBindings;
587   friend class ash::BrowserDataBackMigrator;
588   friend class ash::LoginEventRecorder;
589   friend class ash::MojoUtils;                     // http://crbug.com/1055467
590   friend class ash::StartupCustomizationDocument;  // http://crosbug.com/11103
591   friend class ash::StartupUtils;
592   friend class base::AdjustOOMScoreHelper;
593   friend class base::ChromeOSVersionInfo;
594   friend class base::Process;
595   friend class base::ScopedAllowBlockingForProc;
596   friend class base::ScopedAllowBlockingForProcessMetrics;
597   friend class base::StackSamplingProfiler;
598   friend class base::android::ScopedAllowBlockingForImportantFileWriter;
599   friend class base::debug::StackTrace;
600   friend class base::subtle::PlatformSharedMemoryRegion;
601   friend class base::win::ScopedAllowBlockingForUserAccountControl;
602   friend class blink::DiskDataAllocator;
603   friend class chromecast::CrashUtil;
604   friend class content::BrowserProcessIOThread;
605   friend class content::DWriteFontProxyImpl;
606   friend class content::NetworkServiceInstancePrivate;
607   friend class content::PepperPrintSettingsManagerImpl;
608   friend class content::RenderProcessHostImpl;
609   friend class content::RenderWidgetHostViewMac;  // http://crbug.com/121917
610   friend class content::
611       ScopedAllowBlockingForViewAura;  // http://crbug.com/332579
612   friend class content::ShellPathProvider;
613   friend class content::WebContentsViewMac;
614   friend class cronet::CronetContext;
615   friend class cronet::CronetPrefsManager;
616   friend class crosapi::LacrosThreadTypeDelegate;
617   friend class crypto::ScopedAllowBlockingForNSS;  // http://crbug.com/59847
618   friend class drive::FakeDriveService;
619   friend class extensions::InstalledLoader;
620   friend class extensions::UnpackedInstaller;
621   friend class font_service::internal::MappedFontFile;
622   friend class ios_web_view::WebViewBrowserState;
623   friend class io_thread::IOSIOThread;
624   friend class media::FileVideoCaptureDeviceFactory;
625   friend class memory_instrumentation::OSMetrics;
626   friend class memory_pressure::UserLevelMemoryPressureSignalGenerator;
627   friend class metrics::AndroidMetricsServiceClient;
628   friend class metrics::CleanExitBeacon;
629   friend class module_installer::ScopedAllowModulePakLoad;
630   friend class mojo::CoreLibraryInitializer;
631   friend class net::GSSAPISharedLibrary;    // http://crbug.com/66702
632   friend class net::ProxyConfigServiceWin;  // http://crbug.com/61453
633   friend class net::
634       ScopedAllowBlockingForSettingGetter;  // http://crbug.com/69057
635   friend class printing::LocalPrinterHandlerDefault;
636   friend class printing::PrintBackendServiceManager;
637   friend class printing::PrinterQuery;
638   friend class remote_cocoa::
639       DroppedScreenShotCopierMac;  // https://crbug.com/1148078
640   friend class remote_cocoa::SelectFileDialogBridge;
641   friend class remoting::
642       ScopedBypassIOThreadRestrictions;  // http://crbug.com/1144161
643   friend class ui::DrmDisplayHostManager;
644   friend class ui::ScopedAllowBlockingForGbmSurface;
645   friend class ui::SelectFileDialogLinux;
646   friend class weblayer::BrowserContextImpl;
647   friend class weblayer::ContentBrowserClientImpl;
648   friend class weblayer::ProfileImpl;
649   friend class weblayer::WebLayerPathProvider;
650 #if BUILDFLAG(IS_MAC)
651   friend class printing::PrintBackendServiceImpl;
652 #endif
653 #if BUILDFLAG(IS_WIN)
654   friend class base::win::OSInfo;
655   friend class content::WebContentsImpl;  // http://crbug.com/1262162
656 #endif
657 
658   // Sorted by function name (with namespace), ignoring the return type.
659   friend bool ::EnsureBrowserStateDirectoriesCreated(const base::FilePath&,
660                                                      const base::FilePath&,
661                                                      const base::FilePath&);
662   friend Profile* ::GetLastProfileMac();  // http://crbug.com/1176734
663   friend bool ::HasWaylandDisplay(
664       base::Environment* env);  // http://crbug.com/1246928
665   friend bool ash::CameraAppUIShouldEnableLocalOverride(const std::string&);
666   friend void base::GetNSExecutablePath(base::FilePath*);
667   friend bool base::internal::ReadProcFile(const FilePath& file,
668                                            std::string* buffer);
669   friend bool chrome::PathProvider(int,
670                                    base::FilePath*);  // http://crbug.com/259796
671   friend void chrome::SessionEnding();
672   friend bool chromeos::system::IsCoreSchedulingAvailable();
673   friend int chromeos::system::NumberOfPhysicalCores();
674   friend base::File content::CreateFileForDrop(
675       base::FilePath* file_path);  // http://crbug.com/110709
676   friend bool disk_cache::CleanupDirectorySync(const base::FilePath&);
677   friend bool gl::init::InitializeStaticGLBindings(gl::GLImplementationParts);
678 
679   ScopedAllowBlocking(const Location& from_here = Location::Current());
680   ~ScopedAllowBlocking();
681 
682 #if DCHECK_IS_ON()
683   const AutoReset<BooleanWithStack> resetter_;
684 #endif
685 };
686 
687 class [[maybe_unused, nodiscard]] ScopedAllowBlockingForTesting {
688  public:
689   ScopedAllowBlockingForTesting() = default;
690 
691   ScopedAllowBlockingForTesting(const ScopedAllowBlockingForTesting&) = delete;
692   ScopedAllowBlockingForTesting& operator=(
693       const ScopedAllowBlockingForTesting&) = delete;
694 
695   ~ScopedAllowBlockingForTesting() = default;
696 
697  private:
698 #if DCHECK_IS_ON()
699   ScopedAllowBlocking scoped_allow_blocking_;
700 #endif
701 };
702 
703 INLINE_OR_NOT_TAIL_CALLED void DisallowBaseSyncPrimitives()
704     EMPTY_BODY_IF_DCHECK_IS_OFF;
705 
706 // Disallows singletons within its scope.
707 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowBaseSyncPrimitives {
708  public:
709   ScopedDisallowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF;
710 
711   ScopedDisallowBaseSyncPrimitives(const ScopedDisallowBaseSyncPrimitives&) =
712       delete;
713   ScopedDisallowBaseSyncPrimitives& operator=(
714       const ScopedDisallowBaseSyncPrimitives&) = delete;
715 
716   ~ScopedDisallowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF;
717 
718  private:
719 #if DCHECK_IS_ON()
720   const AutoReset<BooleanWithStack> resetter_;
721 #endif
722 };
723 
724 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedAllowBaseSyncPrimitives {
725  public:
726   ScopedAllowBaseSyncPrimitives(const ScopedAllowBaseSyncPrimitives&) = delete;
727   ScopedAllowBaseSyncPrimitives& operator=(
728       const ScopedAllowBaseSyncPrimitives&) = delete;
729 
730  private:
731   // This can only be instantiated by friends. Use
732   // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend
733   // requirement.
734   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest,
735                            ScopedAllowBaseSyncPrimitives);
736   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest,
737                            ScopedAllowBaseSyncPrimitivesResetsState);
738   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest,
739                            ScopedAllowBaseSyncPrimitivesWithBlockingDisallowed);
740 
741   // Allowed usage:
742   // Sorted by class name (with namespace).
743   friend class ::ChromeNSSCryptoModuleDelegate;
744   friend class ::tracing::FuchsiaPerfettoProducerConnector;
745   friend class android_webview::JsSandboxIsolate;
746   friend class base::SimpleThread;
747   friend class base::internal::GetAppOutputScopedAllowBaseSyncPrimitives;
748   friend class blink::IdentifiabilityActiveSampler;
749   friend class blink::SourceStream;
750   friend class blink::VideoTrackRecorderImplContextProvider;
751   friend class blink::WorkerThread;
752   friend class blink::scheduler::NonMainThreadImpl;
753   friend class cc::CategorizedWorkerPoolImpl;
754   friend class cc::CategorizedWorkerPoolJob;
755   friend class chrome_cleaner::ResetShortcutsComponent;
756   friend class chrome_cleaner::SystemReportComponent;
757   friend class content::BrowserMainLoop;
758   friend class content::BrowserProcessIOThread;
759   friend class content::DWriteFontCollectionProxy;
760   friend class content::RendererBlinkPlatformImpl;
761   friend class content::ServiceWorkerContextClient;
762   friend class device::UsbContext;
763   friend class enterprise_connectors::LinuxKeyRotationCommand;
764   friend class functions::ExecScriptScopedAllowBaseSyncPrimitives;
765   friend class history_report::HistoryReportJniBridge;
766   friend class internal::TaskTracker;
767   friend class leveldb::port::CondVar;
768   friend class nearby::chrome::ScheduledExecutor;
769   friend class nearby::chrome::SubmittableExecutor;
770   friend class media::AudioOutputDevice;
771   friend class media::BlockingUrlProtocol;
772   friend class media::MojoVideoEncodeAccelerator;
773   friend class mojo::core::ScopedIPCSupport;
774   friend class net::MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives;
775   friend class rlz_lib::FinancialPing;
776   friend class shell_integration_linux::
777       LaunchXdgUtilityScopedAllowBaseSyncPrimitives;
778   friend class storage::ObfuscatedFileUtil;
779   friend class syncer::HttpBridge;
780   friend class syncer::GetLocalChangesRequest;
781   friend class updater::SystemctlLauncherScopedAllowBaseSyncPrimitives;
782   friend class viz::ClientGpuMemoryBufferManager;
783   friend class webrtc::DesktopConfigurationMonitor;
784 
785   // Usage that should be fixed:
786   // Sorted by class name (with namespace).
787   friend class ::NativeBackendKWallet;  // http://crbug.com/125331
788   friend class ::ash::system::
789       StatisticsProviderImpl;                      // http://crbug.com/125385
790   friend class blink::VideoFrameResourceProvider;  // http://crbug.com/878070
791 
792   ScopedAllowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF;
793   ~ScopedAllowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF;
794 
795 #if DCHECK_IS_ON()
796   const AutoReset<BooleanWithStack> resetter_;
797 #endif
798 };
799 
800 class BASE_EXPORT
801     [[maybe_unused,
802       nodiscard]] ScopedAllowBaseSyncPrimitivesOutsideBlockingScope {
803  public:
804   ScopedAllowBaseSyncPrimitivesOutsideBlockingScope(
805       const ScopedAllowBaseSyncPrimitivesOutsideBlockingScope&) = delete;
806   ScopedAllowBaseSyncPrimitivesOutsideBlockingScope& operator=(
807       const ScopedAllowBaseSyncPrimitivesOutsideBlockingScope&) = delete;
808 
809  private:
810   // This can only be instantiated by friends. Use
811   // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend
812   // requirement.
813   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest,
814                            ScopedAllowBaseSyncPrimitivesOutsideBlockingScope);
815   FRIEND_TEST_ALL_PREFIXES(
816       ThreadRestrictionsTest,
817       ScopedAllowBaseSyncPrimitivesOutsideBlockingScopeResetsState);
818 
819   // Allowed usage:
820   // Sorted by class name (with namespace).
821   friend class ::BrowserProcessImpl;  // http://crbug.com/125207
822   friend class ::KeyStorageLinux;
823   friend class ::NativeDesktopMediaList;
824   friend class android::JavaHandlerThread;
825   friend class android_webview::
826       AwFormDatabaseService;  // http://crbug.com/904431
827   friend class android_webview::CookieManager;
828   friend class android_webview::VizCompositorThreadRunnerWebView;
829   friend class audio::OutputDevice;
830   friend class base::FileDescriptorWatcher;
831   friend class base::ScopedAllowThreadRecallForStackSamplingProfiler;
832   friend class base::StackSamplingProfiler;
833   friend class base::internal::JobTaskSource;
834   friend class base::sequence_manager::internal::TaskQueueImpl;
835   friend class blink::LegacyWebRtcVideoFrameAdapter;
836   friend class blink::RTCVideoDecoderAdapter;
837   friend class blink::RTCVideoEncoder;
838   friend class blink::WebRtcVideoFrameAdapter;
839   friend class cc::CategorizedWorkerPoolImpl;
840   friend class cc::CategorizedWorkerPoolJob;
841   friend class cc::CategorizedWorkerPool;
842   friend class cc::TileTaskManagerImpl;
843   friend class content::DesktopCaptureDevice;
844   friend class content::EmergencyTraceFinalisationCoordinator;
845   friend class content::InProcessUtilityThread;
846   friend class content::RenderProcessHost;
847   friend class content::RTCVideoDecoder;
848   friend class content::SandboxHostLinux;
849   friend class content::ScopedAllowWaitForDebugURL;
850   friend class content::SynchronousCompositor;
851   friend class content::SynchronousCompositorHost;
852   friend class content::SynchronousCompositorSyncCallBridge;
853   friend class media::AudioInputDevice;
854   friend class media::AudioOutputDevice;
855   friend class media::PaintCanvasVideoRenderer;
856   friend class mojo::SyncCallRestrictions;
857   friend class mojo::core::ipcz_driver::MojoTrap;
858   friend class net::NetworkConfigWatcherMacThread;
859   friend class ui::DrmThreadProxy;
860   friend class viz::HostGpuMemoryBufferManager;
861   friend class vr::VrShell;
862 
863   // Usage that should be fixed:
864   friend class ::chromeos::BlockingMethodCaller;  // http://crbug.com/125360
865   friend class base::Thread;                      // http://crbug.com/918039
866   friend class cc::CompletionEvent;               // http://crbug.com/902653
867   friend class content::
868       BrowserGpuChannelHostFactory;                 // http://crbug.com/125248
869   friend class content::TextInputClientMac;         // http://crbug.com/121917
870   friend class dbus::Bus;                           // http://crbug.com/125222
871   friend class discardable_memory::
872       ClientDiscardableSharedMemoryManager;         // http://crbug.com/1396355
873   friend class disk_cache::BackendImpl;             // http://crbug.com/74623
874   friend class disk_cache::InFlightIO;              // http://crbug.com/74623
875   friend class midi::TaskService;                   // https://crbug.com/796830
876   friend class net::
877       MultiThreadedProxyResolverScopedAllowJoinOnIO;  // http://crbug.com/69710
878   friend class net::NetworkChangeNotifierMac;         // http://crbug.com/125097
879   friend class net::internal::AddressTrackerLinux;    // http://crbug.com/125097
880   friend class proxy_resolver::
881       ScopedAllowThreadJoinForProxyResolverV8Tracing;  // http://crbug.com/69710
882   friend class remoting::AutoThread;  // https://crbug.com/944316
883   friend class remoting::protocol::
884       ScopedAllowSyncPrimitivesForWebRtcDataStreamAdapter;  // http://b/233844893
885   friend class remoting::protocol::
886       ScopedAllowSyncPrimitivesForWebRtcTransport;  // http://crbug.com/1198501
887   friend class remoting::protocol::
888       ScopedAllowThreadJoinForWebRtcTransport;  // http://crbug.com/660081
889   // Not used in production yet, https://crbug.com/844078.
890   friend class service_manager::ServiceProcessLauncher;
891   friend class ui::WindowResizeHelperMac;  // http://crbug.com/902829
892 
893   ScopedAllowBaseSyncPrimitivesOutsideBlockingScope(
894       const Location& from_here = Location::Current());
895 
896   ~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope();
897 
898 #if DCHECK_IS_ON()
899   const AutoReset<BooleanWithStack> resetter_;
900 #endif
901 };
902 
903 // Allow base-sync-primitives in tests, doesn't require explicit friend'ing like
904 // ScopedAllowBaseSyncPrimitives-types aimed at production do.
905 // Note: For WaitableEvents in the test logic, base::TestWaitableEvent is
906 // exposed as a convenience to avoid the need for
907 // ScopedAllowBaseSyncPrimitivesForTesting.
908 class BASE_EXPORT
909     [[maybe_unused, nodiscard]] ScopedAllowBaseSyncPrimitivesForTesting {
910  public:
911   ScopedAllowBaseSyncPrimitivesForTesting() DEFAULT_IF_DCHECK_IS_OFF;
912 
913   ScopedAllowBaseSyncPrimitivesForTesting(
914       const ScopedAllowBaseSyncPrimitivesForTesting&) = delete;
915   ScopedAllowBaseSyncPrimitivesForTesting& operator=(
916       const ScopedAllowBaseSyncPrimitivesForTesting&) = delete;
917 
918   ~ScopedAllowBaseSyncPrimitivesForTesting() DEFAULT_IF_DCHECK_IS_OFF;
919 
920  private:
921 #if DCHECK_IS_ON()
922   const AutoReset<BooleanWithStack> resetter_;
923 #endif
924 };
925 
926 // Counterpart to base::DisallowUnresponsiveTasks() for tests to allow them to
927 // block their thread after it was banned.
928 class BASE_EXPORT
929     [[maybe_unused, nodiscard]] ScopedAllowUnresponsiveTasksForTesting {
930  public:
931   ScopedAllowUnresponsiveTasksForTesting() DEFAULT_IF_DCHECK_IS_OFF;
932 
933   ScopedAllowUnresponsiveTasksForTesting(
934       const ScopedAllowUnresponsiveTasksForTesting&) = delete;
935   ScopedAllowUnresponsiveTasksForTesting& operator=(
936       const ScopedAllowUnresponsiveTasksForTesting&) = delete;
937 
938   ~ScopedAllowUnresponsiveTasksForTesting() DEFAULT_IF_DCHECK_IS_OFF;
939 
940  private:
941 #if DCHECK_IS_ON()
942   const AutoReset<BooleanWithStack> base_sync_resetter_;
943   const AutoReset<BooleanWithStack> blocking_resetter_;
944   const AutoReset<BooleanWithStack> cpu_resetter_;
945 #endif
946 };
947 
948 namespace internal {
949 
950 // Asserts that waiting on a //base sync primitive is allowed in the current
951 // scope.
952 INLINE_OR_NOT_TAIL_CALLED void AssertBaseSyncPrimitivesAllowed()
953     EMPTY_BODY_IF_DCHECK_IS_OFF;
954 
955 // Resets all thread restrictions on the current thread.
956 INLINE_OR_NOT_TAIL_CALLED void ResetThreadRestrictionsForTesting()
957     EMPTY_BODY_IF_DCHECK_IS_OFF;
958 
959 // Check whether the current thread is allowed to use singletons (Singleton /
960 // LazyInstance).  DCHECKs if not.
961 INLINE_OR_NOT_TAIL_CALLED void AssertSingletonAllowed()
962     EMPTY_BODY_IF_DCHECK_IS_OFF;
963 
964 }  // namespace internal
965 
966 // Disallow using singleton on the current thread.
967 INLINE_OR_NOT_TAIL_CALLED void DisallowSingleton() EMPTY_BODY_IF_DCHECK_IS_OFF;
968 
969 // Disallows singletons within its scope.
970 class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowSingleton {
971  public:
972   ScopedDisallowSingleton() DEFAULT_IF_DCHECK_IS_OFF;
973 
974   ScopedDisallowSingleton(const ScopedDisallowSingleton&) = delete;
975   ScopedDisallowSingleton& operator=(const ScopedDisallowSingleton&) = delete;
976 
977   ~ScopedDisallowSingleton() DEFAULT_IF_DCHECK_IS_OFF;
978 
979  private:
980 #if DCHECK_IS_ON()
981   const AutoReset<BooleanWithStack> resetter_;
982 #endif
983 };
984 
985 // Asserts that running long CPU work is allowed in the current scope.
986 INLINE_OR_NOT_TAIL_CALLED void AssertLongCPUWorkAllowed()
987     EMPTY_BODY_IF_DCHECK_IS_OFF;
988 
989 INLINE_OR_NOT_TAIL_CALLED void DisallowUnresponsiveTasks()
990     EMPTY_BODY_IF_DCHECK_IS_OFF;
991 
992 // Friend-only methods to permanently allow the current thread to use
993 // blocking/sync-primitives calls. Threads start out in the *allowed* state but
994 // are typically *disallowed* via the above base::Disallow*() methods after
995 // being initialized.
996 //
997 // Only use these to permanently set the allowance on a thread, e.g. on
998 // shutdown. For temporary allowances, use scopers above.
999 class BASE_EXPORT PermanentThreadAllowance {
1000  public:
1001   // Class is merely a namespace-with-friends.
1002   PermanentThreadAllowance() = delete;
1003 
1004  private:
1005   // Sorted by class name (with namespace)
1006   friend class base::TestCustomDisallow;
1007   friend class content::BrowserMainLoop;
1008   friend class content::BrowserTestBase;
1009 #if BUILDFLAG(IS_IOS)
1010   friend class content::ContentMainRunnerImpl;
1011 #endif  // BUILDFLAG(IS_IOS)
1012   friend class web::WebMainLoop;
1013 
1014   static void AllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
1015   static void AllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
1016 };
1017 
1018 #undef INLINE_OR_NOT_TAIL_CALLED
1019 #undef EMPTY_BODY_IF_DCHECK_IS_OFF
1020 #undef DEFAULT_IF_DCHECK_IS_OFF
1021 
1022 }  // namespace base
1023 
1024 #endif  // BASE_THREADING_THREAD_RESTRICTIONS_H_
1025