Home | History | Annotate | Download | only in threading
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      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/base_export.h"
      9 #include "base/gtest_prod_util.h"
     10 #include "base/logging.h"
     11 #include "base/macros.h"
     12 
     13 class BrowserProcessImpl;
     14 class HistogramSynchronizer;
     15 class NativeBackendKWallet;
     16 class KeyStorageLinux;
     17 
     18 namespace android_webview {
     19 class AwFormDatabaseService;
     20 class CookieManager;
     21 class ScopedAllowInitGLBindings;
     22 }
     23 
     24 namespace cc {
     25 class CompletionEvent;
     26 class SingleThreadTaskGraphRunner;
     27 }
     28 namespace chromeos {
     29 class BlockingMethodCaller;
     30 namespace system {
     31 class StatisticsProviderImpl;
     32 }
     33 }
     34 namespace chrome_browser_net {
     35 class Predictor;
     36 }
     37 namespace content {
     38 class BrowserGpuChannelHostFactory;
     39 class BrowserGpuMemoryBufferManager;
     40 class BrowserMainLoop;
     41 class BrowserProcessSubThread;
     42 class BrowserShutdownProfileDumper;
     43 class BrowserTestBase;
     44 class CategorizedWorkerPool;
     45 class GpuProcessTransportFactory;
     46 class NestedMessagePumpAndroid;
     47 class ScopedAllowWaitForAndroidLayoutTests;
     48 class ScopedAllowWaitForDebugURL;
     49 class SessionStorageDatabase;
     50 class SoftwareOutputDeviceMus;
     51 class ServiceWorkerSubresourceLoader;
     52 class SynchronousCompositor;
     53 class SynchronousCompositorHost;
     54 class SynchronousCompositorSyncCallBridge;
     55 class TextInputClientMac;
     56 }  // namespace content
     57 namespace cronet {
     58 class CronetPrefsManager;
     59 class CronetURLRequestContext;
     60 }  // namespace cronet
     61 namespace dbus {
     62 class Bus;
     63 }
     64 namespace disk_cache {
     65 class BackendImpl;
     66 class InFlightIO;
     67 }
     68 namespace functions {
     69 class ExecScriptScopedAllowBaseSyncPrimitives;
     70 }
     71 namespace gpu {
     72 class GpuChannelHost;
     73 }
     74 namespace leveldb {
     75 class LevelDBMojoProxy;
     76 }
     77 namespace media {
     78 class AudioInputDevice;
     79 class BlockingUrlProtocol;
     80 }
     81 namespace midi {
     82 class TaskService;  // https://crbug.com/796830
     83 }
     84 namespace mojo {
     85 class CoreLibraryInitializer;
     86 class SyncCallRestrictions;
     87 namespace core {
     88 class ScopedIPCSupport;
     89 }
     90 }
     91 namespace rlz_lib {
     92 class FinancialPing;
     93 }
     94 namespace ui {
     95 class CommandBufferClientImpl;
     96 class CommandBufferLocal;
     97 class GpuState;
     98 class MaterialDesignController;
     99 }
    100 namespace net {
    101 class MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives;
    102 class NetworkChangeNotifierMac;
    103 namespace internal {
    104 class AddressTrackerLinux;
    105 }
    106 }
    107 
    108 namespace remoting {
    109 class AutoThread;
    110 }
    111 
    112 namespace resource_coordinator {
    113 class TabManagerDelegate;
    114 }
    115 
    116 namespace service_manager {
    117 class ServiceProcessLauncher;
    118 }
    119 
    120 namespace shell_integration {
    121 class LaunchXdgUtilityScopedAllowBaseSyncPrimitives;
    122 }
    123 
    124 namespace ui {
    125 class WindowResizeHelperMac;
    126 }
    127 
    128 namespace views {
    129 class ScreenMus;
    130 }
    131 
    132 namespace viz {
    133 class HostGpuMemoryBufferManager;
    134 }
    135 
    136 namespace webrtc {
    137 class DesktopConfigurationMonitor;
    138 }
    139 
    140 namespace base {
    141 
    142 namespace android {
    143 class JavaHandlerThread;
    144 }
    145 
    146 namespace internal {
    147 class TaskTracker;
    148 }
    149 
    150 class GetAppOutputScopedAllowBaseSyncPrimitives;
    151 class SimpleThread;
    152 class StackSamplingProfiler;
    153 class Thread;
    154 class ThreadTestHelper;
    155 
    156 #if DCHECK_IS_ON()
    157 #define INLINE_IF_DCHECK_IS_OFF BASE_EXPORT
    158 #define EMPTY_BODY_IF_DCHECK_IS_OFF
    159 #else
    160 #define INLINE_IF_DCHECK_IS_OFF inline
    161 #define EMPTY_BODY_IF_DCHECK_IS_OFF \
    162   {}
    163 #endif
    164 
    165 // A "blocking call" refers to any call that causes the calling thread to wait
    166 // off-CPU. It includes but is not limited to calls that wait on synchronous
    167 // file I/O operations: read or write a file from disk, interact with a pipe or
    168 // a socket, rename or delete a file, enumerate files in a directory, etc.
    169 // Acquiring a low contention lock is not considered a blocking call.
    170 
    171 // Asserts that blocking calls are allowed in the current scope.
    172 //
    173 // Style tip: It's best if you put AssertBlockingAllowed() checks as close to
    174 // the blocking call as possible. For example:
    175 //
    176 // void ReadFile() {
    177 //   PreWork();
    178 //
    179 //   base::AssertBlockingAllowed();
    180 //   fopen(...);
    181 //
    182 //   PostWork();
    183 // }
    184 //
    185 // void Bar() {
    186 //   ReadFile();
    187 // }
    188 //
    189 // void Foo() {
    190 //   Bar();
    191 // }
    192 INLINE_IF_DCHECK_IS_OFF void AssertBlockingAllowed()
    193     EMPTY_BODY_IF_DCHECK_IS_OFF;
    194 
    195 // Disallows blocking on the current thread.
    196 INLINE_IF_DCHECK_IS_OFF void DisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
    197 
    198 // Disallows blocking calls within its scope.
    199 class BASE_EXPORT ScopedDisallowBlocking {
    200  public:
    201   ScopedDisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
    202   ~ScopedDisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
    203 
    204  private:
    205 #if DCHECK_IS_ON()
    206   const bool was_disallowed_;
    207 #endif
    208 
    209   DISALLOW_COPY_AND_ASSIGN(ScopedDisallowBlocking);
    210 };
    211 
    212 // ScopedAllowBlocking(ForTesting) allow blocking calls within a scope where
    213 // they are normally disallowed.
    214 //
    215 // Avoid using this. Prefer making blocking calls from tasks posted to
    216 // base::TaskScheduler with base::MayBlock().
    217 //
    218 // Where unavoidable, put ScopedAllow* instances in the narrowest scope possible
    219 // in the caller making the blocking call but no further down. That is: if a
    220 // Cleanup() method needs to do a blocking call, document Cleanup() as blocking
    221 // and add a ScopedAllowBlocking instance in callers that can't avoid making
    222 // this call from a context where blocking is banned, as such:
    223 //   void Client::MyMethod() {
    224 //     (...)
    225 //     {
    226 //       // Blocking is okay here because XYZ.
    227 //       ScopedAllowBlocking allow_blocking;
    228 //       my_foo_->Cleanup();
    229 //     }
    230 //     (...)
    231 //   }
    232 //
    233 //   // This method can block.
    234 //   void Foo::Cleanup() {
    235 //     // Do NOT add the ScopedAllowBlocking in Cleanup() directly as that hides
    236 //     // its blocking nature from unknowing callers and defeats the purpose of
    237 //     // these checks.
    238 //     FlushStateToDisk();
    239 //   }
    240 //
    241 // Note: In rare situations where the blocking call is an implementation detail
    242 // (i.e. the impl makes a call that invokes AssertBlockingAllowed() but it
    243 // somehow knows that in practice this will not block), it might be okay to hide
    244 // the ScopedAllowBlocking instance in the impl with a comment explaining why
    245 // that's okay.
    246 class BASE_EXPORT ScopedAllowBlocking {
    247  private:
    248   // This can only be instantiated by friends. Use ScopedAllowBlockingForTesting
    249   // in unit tests to avoid the friend requirement.
    250   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, ScopedAllowBlocking);
    251   friend class android_webview::ScopedAllowInitGLBindings;
    252   friend class content::BrowserProcessSubThread;
    253   friend class content::GpuProcessTransportFactory;
    254   friend class cronet::CronetPrefsManager;
    255   friend class cronet::CronetURLRequestContext;
    256   friend class media::AudioInputDevice;
    257   friend class mojo::CoreLibraryInitializer;
    258   friend class resource_coordinator::TabManagerDelegate;  // crbug.com/778703
    259   friend class ui::MaterialDesignController;
    260   friend class ScopedAllowBlockingForTesting;
    261   friend class StackSamplingProfiler;
    262 
    263   ScopedAllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
    264   ~ScopedAllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
    265 
    266 #if DCHECK_IS_ON()
    267   const bool was_disallowed_;
    268 #endif
    269 
    270   DISALLOW_COPY_AND_ASSIGN(ScopedAllowBlocking);
    271 };
    272 
    273 class ScopedAllowBlockingForTesting {
    274  public:
    275   ScopedAllowBlockingForTesting() {}
    276   ~ScopedAllowBlockingForTesting() {}
    277 
    278  private:
    279 #if DCHECK_IS_ON()
    280   ScopedAllowBlocking scoped_allow_blocking_;
    281 #endif
    282 
    283   DISALLOW_COPY_AND_ASSIGN(ScopedAllowBlockingForTesting);
    284 };
    285 
    286 // "Waiting on a //base sync primitive" refers to calling one of these methods:
    287 // - base::WaitableEvent::*Wait*
    288 // - base::ConditionVariable::*Wait*
    289 // - base::Process::WaitForExit*
    290 
    291 // Disallows waiting on a //base sync primitive on the current thread.
    292 INLINE_IF_DCHECK_IS_OFF void DisallowBaseSyncPrimitives()
    293     EMPTY_BODY_IF_DCHECK_IS_OFF;
    294 
    295 // ScopedAllowBaseSyncPrimitives(ForTesting)(OutsideBlockingScope) allow waiting
    296 // on a //base sync primitive within a scope where this is normally disallowed.
    297 //
    298 // Avoid using this.
    299 //
    300 // Instead of waiting on a WaitableEvent or a ConditionVariable, put the work
    301 // that should happen after the wait in a callback and post that callback from
    302 // where the WaitableEvent or ConditionVariable would have been signaled. If
    303 // something needs to be scheduled after many tasks have executed, use
    304 // base::BarrierClosure.
    305 //
    306 // On Windows, join processes asynchronously using base::win::ObjectWatcher.
    307 
    308 // This can only be used in a scope where blocking is allowed.
    309 class BASE_EXPORT ScopedAllowBaseSyncPrimitives {
    310  private:
    311   // This can only be instantiated by friends. Use
    312   // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend
    313   // requirement.
    314   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest,
    315                            ScopedAllowBaseSyncPrimitives);
    316   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest,
    317                            ScopedAllowBaseSyncPrimitivesResetsState);
    318   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest,
    319                            ScopedAllowBaseSyncPrimitivesWithBlockingDisallowed);
    320   friend class base::GetAppOutputScopedAllowBaseSyncPrimitives;
    321   friend class content::BrowserProcessSubThread;
    322   friend class content::SessionStorageDatabase;
    323   friend class functions::ExecScriptScopedAllowBaseSyncPrimitives;
    324   friend class leveldb::LevelDBMojoProxy;
    325   friend class media::BlockingUrlProtocol;
    326   friend class mojo::core::ScopedIPCSupport;
    327   friend class net::MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives;
    328   friend class rlz_lib::FinancialPing;
    329   friend class shell_integration::LaunchXdgUtilityScopedAllowBaseSyncPrimitives;
    330   friend class webrtc::DesktopConfigurationMonitor;
    331   friend class content::ServiceWorkerSubresourceLoader;
    332   friend class viz::HostGpuMemoryBufferManager;
    333 
    334   ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
    335   ~ScopedAllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
    336 
    337 #if DCHECK_IS_ON()
    338   const bool was_disallowed_;
    339 #endif
    340 
    341   DISALLOW_COPY_AND_ASSIGN(ScopedAllowBaseSyncPrimitives);
    342 };
    343 
    344 // This can be used in a scope where blocking is disallowed.
    345 class BASE_EXPORT ScopedAllowBaseSyncPrimitivesOutsideBlockingScope {
    346  private:
    347   // This can only be instantiated by friends. Use
    348   // ScopedAllowBaseSyncPrimitivesForTesting in unit tests to avoid the friend
    349   // requirement.
    350   FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest,
    351                            ScopedAllowBaseSyncPrimitivesOutsideBlockingScope);
    352   FRIEND_TEST_ALL_PREFIXES(
    353       ThreadRestrictionsTest,
    354       ScopedAllowBaseSyncPrimitivesOutsideBlockingScopeResetsState);
    355   friend class ::KeyStorageLinux;
    356   friend class content::SynchronousCompositor;
    357   friend class content::SynchronousCompositorHost;
    358   friend class content::SynchronousCompositorSyncCallBridge;
    359   friend class midi::TaskService;  // https://crbug.com/796830
    360   // Not used in production yet, https://crbug.com/844078.
    361   friend class service_manager::ServiceProcessLauncher;
    362 
    363   ScopedAllowBaseSyncPrimitivesOutsideBlockingScope()
    364       EMPTY_BODY_IF_DCHECK_IS_OFF;
    365   ~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope()
    366       EMPTY_BODY_IF_DCHECK_IS_OFF;
    367 
    368 #if DCHECK_IS_ON()
    369   const bool was_disallowed_;
    370 #endif
    371 
    372   DISALLOW_COPY_AND_ASSIGN(ScopedAllowBaseSyncPrimitivesOutsideBlockingScope);
    373 };
    374 
    375 // This can be used in tests without being a friend of
    376 // ScopedAllowBaseSyncPrimitives(OutsideBlockingScope).
    377 class BASE_EXPORT ScopedAllowBaseSyncPrimitivesForTesting {
    378  public:
    379   ScopedAllowBaseSyncPrimitivesForTesting() EMPTY_BODY_IF_DCHECK_IS_OFF;
    380   ~ScopedAllowBaseSyncPrimitivesForTesting() EMPTY_BODY_IF_DCHECK_IS_OFF;
    381 
    382  private:
    383 #if DCHECK_IS_ON()
    384   const bool was_disallowed_;
    385 #endif
    386 
    387   DISALLOW_COPY_AND_ASSIGN(ScopedAllowBaseSyncPrimitivesForTesting);
    388 };
    389 
    390 namespace internal {
    391 
    392 // Asserts that waiting on a //base sync primitive is allowed in the current
    393 // scope.
    394 INLINE_IF_DCHECK_IS_OFF void AssertBaseSyncPrimitivesAllowed()
    395     EMPTY_BODY_IF_DCHECK_IS_OFF;
    396 
    397 // Resets all thread restrictions on the current thread.
    398 INLINE_IF_DCHECK_IS_OFF void ResetThreadRestrictionsForTesting()
    399     EMPTY_BODY_IF_DCHECK_IS_OFF;
    400 
    401 }  // namespace internal
    402 
    403 class BASE_EXPORT ThreadRestrictions {
    404  public:
    405   // Constructing a ScopedAllowIO temporarily allows IO for the current
    406   // thread.  Doing this is almost certainly always incorrect.
    407   //
    408   // DEPRECATED. Use ScopedAllowBlocking(ForTesting).
    409   class BASE_EXPORT ScopedAllowIO {
    410    public:
    411     ScopedAllowIO() EMPTY_BODY_IF_DCHECK_IS_OFF;
    412     ~ScopedAllowIO() EMPTY_BODY_IF_DCHECK_IS_OFF;
    413 
    414    private:
    415 #if DCHECK_IS_ON()
    416     const bool was_allowed_;
    417 #endif
    418 
    419     DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO);
    420   };
    421 
    422 #if DCHECK_IS_ON()
    423   // Set whether the current thread to make IO calls.
    424   // Threads start out in the *allowed* state.
    425   // Returns the previous value.
    426   //
    427   // DEPRECATED. Use ScopedAllowBlocking(ForTesting) or ScopedDisallowBlocking.
    428   static bool SetIOAllowed(bool allowed);
    429 
    430   // Set whether the current thread can use singletons.  Returns the previous
    431   // value.
    432   static bool SetSingletonAllowed(bool allowed);
    433 
    434   // Check whether the current thread is allowed to use singletons (Singleton /
    435   // LazyInstance).  DCHECKs if not.
    436   static void AssertSingletonAllowed();
    437 
    438   // Disable waiting on the current thread. Threads start out in the *allowed*
    439   // state. Returns the previous value.
    440   //
    441   // DEPRECATED. Use DisallowBaseSyncPrimitives.
    442   static void DisallowWaiting();
    443 #else
    444   // Inline the empty definitions of these functions so that they can be
    445   // compiled out.
    446   static bool SetIOAllowed(bool allowed) { return true; }
    447   static bool SetSingletonAllowed(bool allowed) { return true; }
    448   static void AssertSingletonAllowed() {}
    449   static void DisallowWaiting() {}
    450 #endif
    451 
    452  private:
    453   // DO NOT ADD ANY OTHER FRIEND STATEMENTS.
    454   // BEGIN ALLOWED USAGE.
    455   friend class android_webview::AwFormDatabaseService;
    456   friend class android_webview::CookieManager;
    457   friend class base::StackSamplingProfiler;
    458   friend class content::BrowserMainLoop;
    459   friend class content::BrowserShutdownProfileDumper;
    460   friend class content::BrowserTestBase;
    461   friend class content::NestedMessagePumpAndroid;
    462   friend class content::ScopedAllowWaitForAndroidLayoutTests;
    463   friend class content::ScopedAllowWaitForDebugURL;
    464   friend class ::HistogramSynchronizer;
    465   friend class internal::TaskTracker;
    466   friend class cc::CompletionEvent;
    467   friend class cc::SingleThreadTaskGraphRunner;
    468   friend class content::CategorizedWorkerPool;
    469   friend class remoting::AutoThread;
    470   friend class ui::WindowResizeHelperMac;
    471   friend class MessagePumpDefault;
    472   friend class SimpleThread;
    473   friend class Thread;
    474   friend class ThreadTestHelper;
    475   friend class PlatformThread;
    476   friend class android::JavaHandlerThread;
    477   friend class mojo::SyncCallRestrictions;
    478   friend class ui::CommandBufferClientImpl;
    479   friend class ui::CommandBufferLocal;
    480   friend class ui::GpuState;
    481 
    482   // END ALLOWED USAGE.
    483   // BEGIN USAGE THAT NEEDS TO BE FIXED.
    484   friend class ::chromeos::BlockingMethodCaller;  // http://crbug.com/125360
    485   friend class ::chromeos::system::StatisticsProviderImpl;  // http://crbug.com/125385
    486   friend class chrome_browser_net::Predictor;     // http://crbug.com/78451
    487   friend class
    488       content::BrowserGpuChannelHostFactory;      // http://crbug.com/125248
    489   friend class
    490       content::BrowserGpuMemoryBufferManager;     // http://crbug.com/420368
    491   friend class content::TextInputClientMac;       // http://crbug.com/121917
    492   friend class dbus::Bus;                         // http://crbug.com/125222
    493   friend class disk_cache::BackendImpl;           // http://crbug.com/74623
    494   friend class disk_cache::InFlightIO;            // http://crbug.com/74623
    495   friend class gpu::GpuChannelHost;               // http://crbug.com/125264
    496   friend class net::internal::AddressTrackerLinux;  // http://crbug.com/125097
    497   friend class net::NetworkChangeNotifierMac;     // http://crbug.com/125097
    498   friend class ::BrowserProcessImpl;              // http://crbug.com/125207
    499   friend class ::NativeBackendKWallet;            // http://crbug.com/125331
    500 #if !defined(OFFICIAL_BUILD)
    501   friend class content::SoftwareOutputDeviceMus;  // Interim non-production code
    502 #endif
    503   friend class views::ScreenMus;
    504 // END USAGE THAT NEEDS TO BE FIXED.
    505 
    506 #if DCHECK_IS_ON()
    507   // DEPRECATED. Use ScopedAllowBaseSyncPrimitives.
    508   static bool SetWaitAllowed(bool allowed);
    509 #else
    510   static bool SetWaitAllowed(bool allowed) { return true; }
    511 #endif
    512 
    513   // Constructing a ScopedAllowWait temporarily allows waiting on the current
    514   // thread.  Doing this is almost always incorrect, which is why we limit who
    515   // can use this through friend.
    516   //
    517   // DEPRECATED. Use ScopedAllowBaseSyncPrimitives.
    518   class BASE_EXPORT ScopedAllowWait {
    519    public:
    520     ScopedAllowWait() EMPTY_BODY_IF_DCHECK_IS_OFF;
    521     ~ScopedAllowWait() EMPTY_BODY_IF_DCHECK_IS_OFF;
    522 
    523    private:
    524 #if DCHECK_IS_ON()
    525     const bool was_allowed_;
    526 #endif
    527 
    528     DISALLOW_COPY_AND_ASSIGN(ScopedAllowWait);
    529   };
    530 
    531   DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions);
    532 };
    533 
    534 }  // namespace base
    535 
    536 #endif  // BASE_THREADING_THREAD_RESTRICTIONS_H_
    537