OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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_THREAD_RESTRICTIONS_H_ | |
6 #define BASE_THREAD_RESTRICTIONS_H_ | |
7 | |
8 #include "base/basictypes.h" | |
9 | |
10 namespace base { | |
11 | |
12 // Certain behavior is disallowed on certain threads. ThreadRestrictions helps | |
13 // enforce these rules. Examples of such rules: | |
14 // | |
15 // * Do not do blocking IO (makes the thread janky) | |
16 // * Do not access Singleton/LazyInstance (may lead to shutdown crashes) | |
17 // | |
18 // Here's more about how the protection works: | |
19 // | |
20 // 1) If a thread should not be allowed to make IO calls, mark it: | |
21 // base::ThreadRestrictions::SetIOAllowed(false); | |
22 // By default, threads *are* allowed to make IO calls. | |
23 // In Chrome browser code, IO calls should be proxied to the File thread. | |
24 // | |
25 // 2) If a function makes a call that will go out to disk, check whether the | |
26 // current thread is allowed: | |
27 // base::ThreadRestrictions::AssertIOAllowed(); | |
28 // | |
29 // ThreadRestrictions does nothing in release builds; it is debug-only. | |
30 // | |
31 // Style tip: where should you put AssertIOAllowed checks? It's best | |
32 // if you put them as close to the disk access as possible, at the | |
33 // lowest level. This rule is simple to follow and helps catch all | |
34 // callers. For example, if your function GoDoSomeBlockingDiskCall() | |
35 // only calls other functions in Chrome and not fopen(), you should go | |
36 // add the AssertIOAllowed checks in the helper functions. | |
37 | |
38 class ThreadRestrictions { | |
39 public: | |
40 // Constructing a ScopedAllowIO temporarily allows IO for the current | |
41 // thread. Doing this is almost certainly always incorrect. | |
42 class ScopedAllowIO { | |
43 public: | |
44 ScopedAllowIO() { previous_value_ = SetIOAllowed(true); } | |
45 ~ScopedAllowIO() { SetIOAllowed(previous_value_); } | |
46 private: | |
47 // Whether IO is allowed when the ScopedAllowIO was constructed. | |
48 bool previous_value_; | |
49 | |
50 DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO); | |
51 }; | |
52 | |
53 // Constructing a ScopedAllowSingleton temporarily allows accessing for the | |
54 // current thread. Doing this is almost always incorrect. | |
55 class ScopedAllowSingleton { | |
56 public: | |
57 ScopedAllowSingleton() { previous_value_ = SetSingletonAllowed(true); } | |
58 ~ScopedAllowSingleton() { SetSingletonAllowed(previous_value_); } | |
59 private: | |
60 // Whether singleton use is allowed when the ScopedAllowSingleton was | |
61 // constructed. | |
62 bool previous_value_; | |
63 | |
64 DISALLOW_COPY_AND_ASSIGN(ScopedAllowSingleton); | |
65 }; | |
66 | |
67 #ifndef NDEBUG | |
68 // Set whether the current thread to make IO calls. | |
69 // Threads start out in the *allowed* state. | |
70 // Returns the previous value. | |
71 static bool SetIOAllowed(bool allowed); | |
72 | |
73 // Check whether the current thread is allowed to make IO calls, | |
74 // and DCHECK if not. See the block comment above the class for | |
75 // a discussion of where to add these checks. | |
76 static void AssertIOAllowed(); | |
77 | |
78 // Set whether the current thread can use singletons. Returns the previous | |
79 // value. | |
80 static bool SetSingletonAllowed(bool allowed); | |
81 | |
82 // Check whether the current thread is allowed to use singletons (Singleton / | |
83 // LazyInstance). DCHECKs if not. | |
84 static void AssertSingletonAllowed(); | |
85 #else | |
86 // In Release builds, inline the empty definitions of these functions so | |
87 // that they can be compiled out. | |
88 static bool SetIOAllowed(bool allowed) { return true; } | |
89 static void AssertIOAllowed() {} | |
90 static bool SetSingletonAllowed(bool allowed) { return true; } | |
91 static void AssertSingletonAllowed() {} | |
92 #endif | |
93 | |
94 private: | |
95 DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions); | |
96 }; | |
97 | |
98 } // namespace base | |
99 | |
100 #endif // BASE_THREAD_RESTRICTIONS_H_ | |
OLD | NEW |