tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

thread_restrictions.h (36295B)


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