thread_restrictions.h revision 58537e28ecd584eab876aee8be7156509866d23a
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef BASE_THREADING_THREAD_RESTRICTIONS_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define BASE_THREADING_THREAD_RESTRICTIONS_H_
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/base_export.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// See comment at top of thread_checker.h
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define ENABLE_THREAD_RESTRICTIONS 1
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ENABLE_THREAD_RESTRICTIONS 0
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class AcceleratedPresenter;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BrowserProcessImpl;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class HistogramSynchronizer;
215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class MetricsService;
225e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class NativeBackendKWallet;
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ScopedAllowWaitForLegacyWebViewApi;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestingAutomationProvider;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace browser_sync {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NonFrontendDataTypeController;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class UIModelWorker;
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace cc {
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class CompletionEvent;
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace chromeos {
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class AudioMixerAlsa;
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class BlockingMethodCaller;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace system {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class StatisticsProviderImpl;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace chrome_browser_net {
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Predictor;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BrowserGpuChannelHostFactory;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BrowserTestBase;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GLHelper;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GpuChannelHost;
485e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class NestedMessagePumpAndroid;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderWidgetHelper;
505e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class ScopedAllowWaitForAndroidLayoutTests;
515e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class TextInputClientMac;
525e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)}
535e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace dbus {
545e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class Bus;
555e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)}
565e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace disk_cache {
575e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class BackendImpl;
585e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class InFlightIO;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioOutputController;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FileStreamPosix;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FileStreamWin;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AddressTrackerLinux;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
715e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace remoting {
725e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class AutoThread;
735e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)}
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
755e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace base {
765e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
775e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)namespace android {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class JavaHandlerThread;
795e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)}
805e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
815e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class SequencedWorkerPool;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SimpleThread;
835e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class Thread;
845e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)class ThreadTestHelper;
855e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Certain behavior is disallowed on certain threads.  ThreadRestrictions helps
875e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// enforce these rules.  Examples of such rules:
885e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)//
895e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// * Do not do blocking IO (makes the thread janky)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// * Do not access Singleton/LazyInstance (may lead to shutdown crashes)
915e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)//
925e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// Here's more about how the protection works:
935e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)//
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1) If a thread should not be allowed to make IO calls, mark it:
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      base::ThreadRestrictions::SetIOAllowed(false);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    By default, threads *are* allowed to make IO calls.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    In Chrome browser code, IO calls should be proxied to the File thread.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2) If a function makes a call that will go out to disk, check whether the
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    current thread is allowed:
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      base::ThreadRestrictions::AssertIOAllowed();
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Style tip: where should you put AssertIOAllowed checks?  It's best
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// if you put them as close to the disk access as possible, at the
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// lowest level.  This rule is simple to follow and helps catch all
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// callers.  For example, if your function GoDoSomeBlockingDiskCall()
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// only calls other functions in Chrome and not fopen(), you should go
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// add the AssertIOAllowed checks in the helper functions.
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BASE_EXPORT ThreadRestrictions {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Constructing a ScopedAllowIO temporarily allows IO for the current
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // thread.  Doing this is almost certainly always incorrect.
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class BASE_EXPORT ScopedAllowIO {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedAllowIO() { previous_value_ = SetIOAllowed(true); }
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ~ScopedAllowIO() { SetIOAllowed(previous_value_); }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Whether IO is allowed when the ScopedAllowIO was constructed.
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool previous_value_;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Constructing a ScopedAllowSingleton temporarily allows accessing for the
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // current thread.  Doing this is almost always incorrect.
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class BASE_EXPORT ScopedAllowSingleton {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedAllowSingleton() { previous_value_ = SetSingletonAllowed(true); }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ~ScopedAllowSingleton() { SetSingletonAllowed(previous_value_); }
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Whether singleton use is allowed when the ScopedAllowSingleton was
1345e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    // constructed.
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool previous_value_;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1375e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(ScopedAllowSingleton);
1385e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  };
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if ENABLE_THREAD_RESTRICTIONS
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set whether the current thread to make IO calls.
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Threads start out in the *allowed* state.
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the previous value.
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool SetIOAllowed(bool allowed);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check whether the current thread is allowed to make IO calls,
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and DCHECK if not.  See the block comment above the class for
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a discussion of where to add these checks.
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void AssertIOAllowed();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set whether the current thread can use singletons.  Returns the previous
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // value.
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool SetSingletonAllowed(bool allowed);
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1555e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  // Check whether the current thread is allowed to use singletons (Singleton /
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // LazyInstance).  DCHECKs if not.
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static void AssertSingletonAllowed();
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Disable waiting on the current thread. Threads start out in the *allowed*
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // state. Returns the previous value.
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void DisallowWaiting();
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check whether the current thread is allowed to wait, and DCHECK if not.
1645e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  static void AssertWaitAllowed();
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Inline the empty definitions of these functions so that they can be
167  // compiled out.
168  static bool SetIOAllowed(bool allowed) { return true; }
169  static void AssertIOAllowed() {}
170  static bool SetSingletonAllowed(bool allowed) { return true; }
171  static void AssertSingletonAllowed() {}
172  static void DisallowWaiting() {}
173  static void AssertWaitAllowed() {}
174#endif
175
176 private:
177  // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to jam or brettw first.
178  // BEGIN ALLOWED USAGE.
179  friend class content::BrowserTestBase;
180  friend class content::NestedMessagePumpAndroid;
181  friend class content::RenderWidgetHelper;
182  friend class content::ScopedAllowWaitForAndroidLayoutTests;
183  friend class ::HistogramSynchronizer;
184  friend class ::ScopedAllowWaitForLegacyWebViewApi;
185  friend class ::TestingAutomationProvider;
186  friend class cc::CompletionEvent;
187  friend class remoting::AutoThread;
188  friend class MessagePumpDefault;
189  friend class SequencedWorkerPool;
190  friend class SimpleThread;
191  friend class Thread;
192  friend class ThreadTestHelper;
193  friend class PlatformThread;
194  friend class android::JavaHandlerThread;
195
196  // END ALLOWED USAGE.
197  // BEGIN USAGE THAT NEEDS TO BE FIXED.
198  friend class ::chromeos::AudioMixerAlsa;        // http://crbug.com/125206
199  friend class ::chromeos::BlockingMethodCaller;  // http://crbug.com/125360
200  friend class ::chromeos::system::StatisticsProviderImpl;  // http://crbug.com/125385
201  friend class browser_sync::NonFrontendDataTypeController;  // http://crbug.com/19757
202  friend class browser_sync::UIModelWorker;       // http://crbug.com/19757
203  friend class chrome_browser_net::Predictor;     // http://crbug.com/78451
204  friend class
205      content::BrowserGpuChannelHostFactory;      // http://crbug.com/125248
206  friend class content::GLHelper;                 // http://crbug.com/125415
207  friend class content::GpuChannelHost;           // http://crbug.com/125264
208  friend class content::TextInputClientMac;       // http://crbug.com/121917
209  friend class dbus::Bus;                         // http://crbug.com/125222
210  friend class disk_cache::BackendImpl;           // http://crbug.com/74623
211  friend class disk_cache::InFlightIO;            // http://crbug.com/74623
212  friend class media::AudioOutputController;      // http://crbug.com/120973
213  friend class net::FileStreamPosix;              // http://crbug.com/115067
214  friend class net::FileStreamWin;                // http://crbug.com/115067
215  friend class net::internal::AddressTrackerLinux;  // http://crbug.com/125097
216  friend class ::AcceleratedPresenter;            // http://crbug.com/125391
217  friend class ::BrowserProcessImpl;              // http://crbug.com/125207
218  friend class ::MetricsService;                  // http://crbug.com/124954
219  friend class ::NativeBackendKWallet;            // http://crbug.com/125331
220  // END USAGE THAT NEEDS TO BE FIXED.
221
222#if ENABLE_THREAD_RESTRICTIONS
223  static bool SetWaitAllowed(bool allowed);
224#else
225  static bool SetWaitAllowed(bool allowed) { return true; }
226#endif
227
228  // Constructing a ScopedAllowWait temporarily allows waiting on the current
229  // thread.  Doing this is almost always incorrect, which is why we limit who
230  // can use this through friend. If you find yourself needing to use this, find
231  // another way. Talk to jam or brettw.
232  class BASE_EXPORT ScopedAllowWait {
233   public:
234    ScopedAllowWait() { previous_value_ = SetWaitAllowed(true); }
235    ~ScopedAllowWait() { SetWaitAllowed(previous_value_); }
236   private:
237    // Whether singleton use is allowed when the ScopedAllowWait was
238    // constructed.
239    bool previous_value_;
240
241    DISALLOW_COPY_AND_ASSIGN(ScopedAllowWait);
242  };
243
244  DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions);
245};
246
247}  // namespace base
248
249#endif  // BASE_THREADING_THREAD_RESTRICTIONS_H_
250