blob: 7489ff4daab55880fe892d7b27eaca997f5a1ef6 [file] [log] [blame]
battre@chromium.org7d937d42012-04-27 22:55:40 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
evan@chromium.orge450cfc2010-10-20 05:28:03 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
brettw@chromium.org5b5f5e02011-01-01 10:01:06 +09005#ifndef BASE_THREADING_THREAD_RESTRICTIONS_H_
6#define BASE_THREADING_THREAD_RESTRICTIONS_H_
evan@chromium.orge450cfc2010-10-20 05:28:03 +09007
darin@chromium.orge585bed2011-08-06 00:34:00 +09008#include "base/base_export.h"
evan@chromium.org7c9cd8b2010-10-23 14:19:20 +09009#include "base/basictypes.h"
10
jam@chromium.org605d18a2012-06-26 12:53:37 +090011// See comment at top of thread_checker.h
12#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
13#define ENABLE_THREAD_RESTRICTIONS 1
14#else
15#define ENABLE_THREAD_RESTRICTIONS 0
16#endif
17
jam@chromium.org786c0b12012-04-27 03:03:58 +090018class BrowserProcessImpl;
jam@chromium.orgd36f6072012-04-28 03:28:36 +090019class HistogramSynchronizer;
jam@chromium.org67ff2392012-04-28 01:42:17 +090020class NativeBackendKWallet;
tedchoc@chromium.org00e5e7d2012-09-07 14:43:10 +090021class ScopedAllowWaitForLegacyWebViewApi;
kevers@chromium.org7439c762012-04-28 00:07:37 +090022
backer@chromium.org6c9aa302012-10-16 06:22:26 +090023namespace cc {
enne@chromium.org531e69e2012-10-23 08:09:55 +090024class CompletionEvent;
weiliangc0965f112015-02-27 03:33:09 +090025class TaskGraphRunner;
backer@chromium.org6c9aa302012-10-16 06:22:26 +090026}
jam@chromium.org786c0b12012-04-27 03:03:58 +090027namespace chromeos {
jam@chromium.org67ff2392012-04-28 01:42:17 +090028class BlockingMethodCaller;
jam@chromium.org35939472012-04-28 05:29:19 +090029namespace system {
30class StatisticsProviderImpl;
31}
jam@chromium.org786c0b12012-04-27 03:03:58 +090032}
jam@chromium.org8ed46142012-04-27 01:34:16 +090033namespace chrome_browser_net {
34class Predictor;
35}
mazda@chromium.org509d6352012-04-28 05:46:47 +090036namespace content {
37class BrowserGpuChannelHostFactory;
reveman80851392014-10-14 05:52:05 +090038class BrowserGpuMemoryBufferManager;
wangxianzhu@chromium.org47df8452013-09-18 17:15:46 +090039class BrowserShutdownProfileDumper;
nileshagrawal@chromium.orgeaeda1f2013-02-05 07:33:17 +090040class BrowserTestBase;
jam@chromium.org8a7e7542012-10-23 05:16:19 +090041class GpuChannelHost;
mnissler@chromium.orga807b7b2013-09-04 03:11:10 +090042class NestedMessagePumpAndroid;
peter@chromium.orge1a44702013-06-21 05:02:21 +090043class ScopedAllowWaitForAndroidLayoutTests;
erikwright74587902015-04-23 23:35:20 +090044class ScopedAllowWaitForDebugURL;
rjkroege36fbab22015-11-19 10:40:47 +090045class SoftwareOutputDeviceMus;
jam@chromium.org8ff19452012-10-30 04:35:57 +090046class TextInputClientMac;
danakj651c3e22015-03-07 10:51:42 +090047} // namespace content
jam@chromium.org17554342012-04-27 04:08:58 +090048namespace dbus {
49class Bus;
50}
jam@chromium.org8ed46142012-04-27 01:34:16 +090051namespace disk_cache {
52class BackendImpl;
53class InFlightIO;
54}
ben05888ea2015-11-10 16:56:16 +090055namespace gles2 {
56class CommandBufferClientImpl;
57}
sky@chromium.org84326df2014-07-24 23:57:28 +090058namespace mojo {
59namespace common {
60class WatcherThreadManager;
61}
62}
jam@chromium.org8ed46142012-04-27 01:34:16 +090063namespace net {
esprehnf4a9f682015-06-19 08:23:07 +090064class NetworkChangeNotifierMac;
pauljensen@chromium.org6e721912012-11-30 02:11:55 +090065namespace internal {
66class AddressTrackerLinux;
67}
jam@chromium.org8ed46142012-04-27 01:34:16 +090068}
69
wez@chromium.org4b67b1f2012-10-10 12:56:12 +090070namespace remoting {
71class AutoThread;
72}
73
taptedef61c042015-09-24 11:51:02 +090074namespace ui {
75class WindowResizeHelperMac;
76}
77
sadrulde036882015-11-24 04:25:16 +090078namespace views {
79class WindowManagerConnection;
80}
81
evan@chromium.orge450cfc2010-10-20 05:28:03 +090082namespace base {
83
kristianm@chromium.orga78bfa92013-08-08 10:31:52 +090084namespace android {
85class JavaHandlerThread;
86}
87
jam@chromium.org8ed46142012-04-27 01:34:16 +090088class SequencedWorkerPool;
89class SimpleThread;
90class Thread;
91class ThreadTestHelper;
92
willchan@chromium.org25726ef2010-11-20 05:34:18 +090093// Certain behavior is disallowed on certain threads. ThreadRestrictions helps
94// enforce these rules. Examples of such rules:
95//
96// * Do not do blocking IO (makes the thread janky)
97// * Do not access Singleton/LazyInstance (may lead to shutdown crashes)
98//
99// Here's more about how the protection works:
evan@chromium.orge450cfc2010-10-20 05:28:03 +0900100//
101// 1) If a thread should not be allowed to make IO calls, mark it:
102// base::ThreadRestrictions::SetIOAllowed(false);
103// By default, threads *are* allowed to make IO calls.
104// In Chrome browser code, IO calls should be proxied to the File thread.
105//
106// 2) If a function makes a call that will go out to disk, check whether the
107// current thread is allowed:
108// base::ThreadRestrictions::AssertIOAllowed();
109//
evan@chromium.orge450cfc2010-10-20 05:28:03 +0900110//
evan@chromium.org7c9cd8b2010-10-23 14:19:20 +0900111// Style tip: where should you put AssertIOAllowed checks? It's best
112// if you put them as close to the disk access as possible, at the
113// lowest level. This rule is simple to follow and helps catch all
114// callers. For example, if your function GoDoSomeBlockingDiskCall()
115// only calls other functions in Chrome and not fopen(), you should go
116// add the AssertIOAllowed checks in the helper functions.
117
darin@chromium.orge585bed2011-08-06 00:34:00 +0900118class BASE_EXPORT ThreadRestrictions {
evan@chromium.orge450cfc2010-10-20 05:28:03 +0900119 public:
evan@chromium.org7c9cd8b2010-10-23 14:19:20 +0900120 // Constructing a ScopedAllowIO temporarily allows IO for the current
evan@chromium.org0f5557b2010-11-02 05:31:45 +0900121 // thread. Doing this is almost certainly always incorrect.
darin@chromium.orge585bed2011-08-06 00:34:00 +0900122 class BASE_EXPORT ScopedAllowIO {
evan@chromium.org7c9cd8b2010-10-23 14:19:20 +0900123 public:
124 ScopedAllowIO() { previous_value_ = SetIOAllowed(true); }
125 ~ScopedAllowIO() { SetIOAllowed(previous_value_); }
126 private:
127 // Whether IO is allowed when the ScopedAllowIO was constructed.
128 bool previous_value_;
129
130 DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO);
131 };
evan@chromium.orgc45c1272010-10-23 08:44:17 +0900132
willchan@chromium.org25726ef2010-11-20 05:34:18 +0900133 // Constructing a ScopedAllowSingleton temporarily allows accessing for the
134 // current thread. Doing this is almost always incorrect.
darin@chromium.orge585bed2011-08-06 00:34:00 +0900135 class BASE_EXPORT ScopedAllowSingleton {
willchan@chromium.org25726ef2010-11-20 05:34:18 +0900136 public:
137 ScopedAllowSingleton() { previous_value_ = SetSingletonAllowed(true); }
138 ~ScopedAllowSingleton() { SetSingletonAllowed(previous_value_); }
139 private:
140 // Whether singleton use is allowed when the ScopedAllowSingleton was
141 // constructed.
142 bool previous_value_;
143
144 DISALLOW_COPY_AND_ASSIGN(ScopedAllowSingleton);
145 };
146
jam@chromium.org6f349482012-06-27 06:47:57 +0900147#if ENABLE_THREAD_RESTRICTIONS
evan@chromium.orge450cfc2010-10-20 05:28:03 +0900148 // Set whether the current thread to make IO calls.
149 // Threads start out in the *allowed* state.
evan@chromium.org7c9cd8b2010-10-23 14:19:20 +0900150 // Returns the previous value.
151 static bool SetIOAllowed(bool allowed);
evan@chromium.orge450cfc2010-10-20 05:28:03 +0900152
153 // Check whether the current thread is allowed to make IO calls,
evan@chromium.org7c9cd8b2010-10-23 14:19:20 +0900154 // and DCHECK if not. See the block comment above the class for
155 // a discussion of where to add these checks.
evan@chromium.orge450cfc2010-10-20 05:28:03 +0900156 static void AssertIOAllowed();
willchan@chromium.org25726ef2010-11-20 05:34:18 +0900157
158 // Set whether the current thread can use singletons. Returns the previous
159 // value.
160 static bool SetSingletonAllowed(bool allowed);
161
162 // Check whether the current thread is allowed to use singletons (Singleton /
163 // LazyInstance). DCHECKs if not.
164 static void AssertSingletonAllowed();
jam@chromium.org8ed46142012-04-27 01:34:16 +0900165
166 // Disable waiting on the current thread. Threads start out in the *allowed*
167 // state. Returns the previous value.
168 static void DisallowWaiting();
169
170 // Check whether the current thread is allowed to wait, and DCHECK if not.
171 static void AssertWaitAllowed();
evan@chromium.orgc45c1272010-10-23 08:44:17 +0900172#else
jam@chromium.org605d18a2012-06-26 12:53:37 +0900173 // Inline the empty definitions of these functions so that they can be
174 // compiled out.
evan@chromium.org7c9cd8b2010-10-23 14:19:20 +0900175 static bool SetIOAllowed(bool allowed) { return true; }
evan@chromium.orgc45c1272010-10-23 08:44:17 +0900176 static void AssertIOAllowed() {}
willchan@chromium.org25726ef2010-11-20 05:34:18 +0900177 static bool SetSingletonAllowed(bool allowed) { return true; }
178 static void AssertSingletonAllowed() {}
jam@chromium.org8ed46142012-04-27 01:34:16 +0900179 static void DisallowWaiting() {}
180 static void AssertWaitAllowed() {}
evan@chromium.orgc45c1272010-10-23 08:44:17 +0900181#endif
evan@chromium.orge450cfc2010-10-20 05:28:03 +0900182
183 private:
jam@chromium.org8ed46142012-04-27 01:34:16 +0900184 // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to jam or brettw first.
185 // BEGIN ALLOWED USAGE.
wangxianzhu@chromium.org47df8452013-09-18 17:15:46 +0900186 friend class content::BrowserShutdownProfileDumper;
nileshagrawal@chromium.orgeaeda1f2013-02-05 07:33:17 +0900187 friend class content::BrowserTestBase;
mnissler@chromium.orga807b7b2013-09-04 03:11:10 +0900188 friend class content::NestedMessagePumpAndroid;
peter@chromium.orge1a44702013-06-21 05:02:21 +0900189 friend class content::ScopedAllowWaitForAndroidLayoutTests;
erikwright74587902015-04-23 23:35:20 +0900190 friend class content::ScopedAllowWaitForDebugURL;
jam@chromium.orgd36f6072012-04-28 03:28:36 +0900191 friend class ::HistogramSynchronizer;
tedchoc@chromium.org00e5e7d2012-09-07 14:43:10 +0900192 friend class ::ScopedAllowWaitForLegacyWebViewApi;
enne@chromium.org531e69e2012-10-23 08:09:55 +0900193 friend class cc::CompletionEvent;
weiliangc0965f112015-02-27 03:33:09 +0900194 friend class cc::TaskGraphRunner;
sky@chromium.org84326df2014-07-24 23:57:28 +0900195 friend class mojo::common::WatcherThreadManager;
wez@chromium.org4b67b1f2012-10-10 12:56:12 +0900196 friend class remoting::AutoThread;
taptedef61c042015-09-24 11:51:02 +0900197 friend class ui::WindowResizeHelperMac;
scherkus@chromium.orgf9672852012-11-14 11:47:50 +0900198 friend class MessagePumpDefault;
jam@chromium.org8ed46142012-04-27 01:34:16 +0900199 friend class SequencedWorkerPool;
200 friend class SimpleThread;
201 friend class Thread;
202 friend class ThreadTestHelper;
epenner@chromium.orged1c9ba2013-05-22 09:01:38 +0900203 friend class PlatformThread;
kristianm@chromium.orga78bfa92013-08-08 10:31:52 +0900204 friend class android::JavaHandlerThread;
ben05888ea2015-11-10 16:56:16 +0900205 friend class gles2::CommandBufferClientImpl;
wez@chromium.org4b67b1f2012-10-10 12:56:12 +0900206
jam@chromium.org8ed46142012-04-27 01:34:16 +0900207 // END ALLOWED USAGE.
208 // BEGIN USAGE THAT NEEDS TO BE FIXED.
jam@chromium.org67ff2392012-04-28 01:42:17 +0900209 friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360
jam@chromium.org35939472012-04-28 05:29:19 +0900210 friend class ::chromeos::system::StatisticsProviderImpl; // http://crbug.com/125385
jam@chromium.org67ff2392012-04-28 01:42:17 +0900211 friend class chrome_browser_net::Predictor; // http://crbug.com/78451
mazda@chromium.org509d6352012-04-28 05:46:47 +0900212 friend class
213 content::BrowserGpuChannelHostFactory; // http://crbug.com/125248
reveman80851392014-10-14 05:52:05 +0900214 friend class
215 content::BrowserGpuMemoryBufferManager; // http://crbug.com/420368
jam@chromium.org8a7e7542012-10-23 05:16:19 +0900216 friend class content::GpuChannelHost; // http://crbug.com/125264
jam@chromium.org8ff19452012-10-30 04:35:57 +0900217 friend class content::TextInputClientMac; // http://crbug.com/121917
jam@chromium.org67ff2392012-04-28 01:42:17 +0900218 friend class dbus::Bus; // http://crbug.com/125222
219 friend class disk_cache::BackendImpl; // http://crbug.com/74623
220 friend class disk_cache::InFlightIO; // http://crbug.com/74623
pauljensen@chromium.org6e721912012-11-30 02:11:55 +0900221 friend class net::internal::AddressTrackerLinux; // http://crbug.com/125097
thakis879553f2015-06-26 00:30:55 +0900222 friend class net::NetworkChangeNotifierMac; // http://crbug.com/125097
jam@chromium.org67ff2392012-04-28 01:42:17 +0900223 friend class ::BrowserProcessImpl; // http://crbug.com/125207
jam@chromium.org67ff2392012-04-28 01:42:17 +0900224 friend class ::NativeBackendKWallet; // http://crbug.com/125331
rjkroege36fbab22015-11-19 10:40:47 +0900225#if !defined(OFFICIAL_BUILD)
226 friend class content::SoftwareOutputDeviceMus; // Interim non-production code
sadrulde036882015-11-24 04:25:16 +0900227 friend class views::WindowManagerConnection;
rjkroege36fbab22015-11-19 10:40:47 +0900228#endif
229// END USAGE THAT NEEDS TO BE FIXED.
jam@chromium.org8ed46142012-04-27 01:34:16 +0900230
jam@chromium.org6f349482012-06-27 06:47:57 +0900231#if ENABLE_THREAD_RESTRICTIONS
jam@chromium.org8ed46142012-04-27 01:34:16 +0900232 static bool SetWaitAllowed(bool allowed);
233#else
234 static bool SetWaitAllowed(bool allowed) { return true; }
235#endif
236
237 // Constructing a ScopedAllowWait temporarily allows waiting on the current
238 // thread. Doing this is almost always incorrect, which is why we limit who
239 // can use this through friend. If you find yourself needing to use this, find
240 // another way. Talk to jam or brettw.
241 class BASE_EXPORT ScopedAllowWait {
242 public:
243 ScopedAllowWait() { previous_value_ = SetWaitAllowed(true); }
244 ~ScopedAllowWait() { SetWaitAllowed(previous_value_); }
245 private:
246 // Whether singleton use is allowed when the ScopedAllowWait was
247 // constructed.
248 bool previous_value_;
249
250 DISALLOW_COPY_AND_ASSIGN(ScopedAllowWait);
251 };
252
willchan@chromium.org25726ef2010-11-20 05:34:18 +0900253 DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions);
evan@chromium.orge450cfc2010-10-20 05:28:03 +0900254};
255
evan@chromium.orge450cfc2010-10-20 05:28:03 +0900256} // namespace base
257
brettw@chromium.org5b5f5e02011-01-01 10:01:06 +0900258#endif // BASE_THREADING_THREAD_RESTRICTIONS_H_