OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // WARNING: You should probably be using Thread (thread.h) instead. Thread is | 5 // WARNING: You should probably be using Thread (thread.h) instead. Thread is |
6 // Chrome's message-loop based Thread abstraction, and if you are a | 6 // Chrome's message-loop based Thread abstraction, and if you are a |
7 // thread running in the browser, there will likely be assumptions | 7 // thread running in the browser, there will likely be assumptions |
8 // that your thread will have an associated message loop. | 8 // that your thread will have an associated message loop. |
9 // | 9 // |
10 // This is a simple thread interface that backs to a native operating system | 10 // This is a simple thread interface that backs to a native operating system |
(...skipping 28 matching lines...) Expand all Loading... |
39 | 39 |
40 #ifndef BASE_THREADING_SIMPLE_THREAD_H_ | 40 #ifndef BASE_THREADING_SIMPLE_THREAD_H_ |
41 #define BASE_THREADING_SIMPLE_THREAD_H_ | 41 #define BASE_THREADING_SIMPLE_THREAD_H_ |
42 | 42 |
43 #include <stddef.h> | 43 #include <stddef.h> |
44 | 44 |
45 #include <queue> | 45 #include <queue> |
46 #include <string> | 46 #include <string> |
47 #include <vector> | 47 #include <vector> |
48 | 48 |
| 49 #include "base/atomic_ref_count.h" |
49 #include "base/base_export.h" | 50 #include "base/base_export.h" |
50 #include "base/compiler_specific.h" | 51 #include "base/compiler_specific.h" |
| 52 #include "base/logging.h" |
| 53 #include "base/macros.h" |
51 #include "base/synchronization/lock.h" | 54 #include "base/synchronization/lock.h" |
52 #include "base/synchronization/waitable_event.h" | 55 #include "base/synchronization/waitable_event.h" |
53 #include "base/threading/platform_thread.h" | 56 #include "base/threading/platform_thread.h" |
54 | 57 |
55 namespace base { | 58 namespace base { |
56 | 59 |
57 // This is the base SimpleThread. You can derive from it and implement the | 60 // This is the base SimpleThread. You can derive from it and implement the |
58 // virtual Run method, or you can use the DelegateSimpleThread interface. | 61 // virtual Run method, or you can use the DelegateSimpleThread interface. |
59 class BASE_EXPORT SimpleThread : public PlatformThread::Delegate { | 62 class BASE_EXPORT SimpleThread : public PlatformThread::Delegate { |
60 public: | 63 public: |
61 class BASE_EXPORT Options { | 64 struct BASE_EXPORT Options { |
62 public: | 65 public: |
63 Options() : stack_size_(0), priority_(ThreadPriority::NORMAL) {} | 66 Options() = default; |
64 explicit Options(ThreadPriority priority) | 67 explicit Options(ThreadPriority priority_in) : priority(priority_in) {} |
65 : stack_size_(0), priority_(priority) {} | 68 ~Options() = default; |
66 ~Options() {} | |
67 | 69 |
68 // We use the standard compiler-supplied copy constructor. | 70 // Allow copies. |
| 71 Options(const Options& other) = default; |
| 72 Options& operator=(const Options& other) = default; |
69 | 73 |
70 // A custom stack size, or 0 for the system default. | 74 // A custom stack size, or 0 for the system default. |
71 void set_stack_size(size_t size) { stack_size_ = size; } | 75 size_t stack_size = 0; |
72 size_t stack_size() const { return stack_size_; } | |
73 | 76 |
74 // A custom thread priority. | 77 ThreadPriority priority = ThreadPriority::NORMAL; |
75 void set_priority(ThreadPriority priority) { priority_ = priority; } | 78 |
76 ThreadPriority priority() const { return priority_; } | 79 // If false, the underlying thread's PlatformThreadHandle will not be kept |
77 private: | 80 // around and as such the SimpleThread instance will not be Join()able and |
78 size_t stack_size_; | 81 // must not be deleted before Run() is invoked. After that, it's up to |
79 ThreadPriority priority_; | 82 // the subclass to determine when it is safe to delete itself, see |
| 83 // DelegateSimpleThread for a safe option. |
| 84 bool joinable = true; |
80 }; | 85 }; |
81 | 86 |
82 // Create a SimpleThread. |options| should be used to manage any specific | 87 // Create a SimpleThread. |options| should be used to manage any specific |
83 // configuration involving the thread creation and management. | 88 // configuration involving the thread creation and management. |
84 // Every thread has a name, in the form of |name_prefix|/TID, for example | 89 // Every thread has a name, in the form of |name_prefix|/TID, for example |
85 // "my_thread/321". The thread will not be created until Start() is called. | 90 // "my_thread/321". The thread will not be created until Start() is called. |
86 explicit SimpleThread(const std::string& name_prefix); | 91 explicit SimpleThread(const std::string& name_prefix); |
87 SimpleThread(const std::string& name_prefix, const Options& options); | 92 SimpleThread(const std::string& name_prefix, const Options& options); |
88 | 93 |
89 ~SimpleThread() override; | 94 ~SimpleThread() override; |
90 | 95 |
91 virtual void Start(); | 96 virtual void Start(); |
92 virtual void Join(); | 97 virtual void Join(); |
93 | 98 |
94 // Subclasses should override the Run method. | 99 // Subclasses should override the Run method. |
95 virtual void Run() = 0; | 100 virtual void Run() = 0; |
96 | 101 |
97 // Return the thread name prefix, or "unnamed" if none was supplied. | 102 // Return the thread name prefix, or "unnamed" if none was supplied. |
98 std::string name_prefix() { return name_prefix_; } | 103 std::string name_prefix() { return name_prefix_; } |
99 | 104 |
100 // Return the completed name including TID, only valid after Start(). | 105 // Return the completed name including TID, only valid after Start(). |
101 std::string name() { return name_; } | 106 std::string name() { return name_; } |
102 | 107 |
103 // Return the thread id, only valid after Start(). | 108 // Return the thread id, only valid after Start(). |
104 PlatformThreadId tid() { return tid_; } | 109 PlatformThreadId tid() { return tid_; } |
105 | 110 |
106 // Return True if Start() has ever been called. | 111 // Return True if Start() has ever been called. |
107 bool HasBeenStarted(); | 112 bool HasBeenStarted(); |
108 | 113 |
109 // Return True if Join() has evern been called. | 114 // Return True if Join() has ever been called. |
110 bool HasBeenJoined() { return joined_; } | 115 bool HasBeenJoined() { return joined_; } |
111 | 116 |
112 // Overridden from PlatformThread::Delegate: | 117 // Overridden from PlatformThread::Delegate: |
113 void ThreadMain() override; | 118 void ThreadMain() override; |
114 | 119 |
115 private: | 120 private: |
116 const std::string name_prefix_; | 121 const std::string name_prefix_; |
117 std::string name_; | 122 std::string name_; |
118 const Options options_; | 123 const Options options_; |
119 PlatformThreadHandle thread_; // PlatformThread handle, invalid after Join! | 124 PlatformThreadHandle thread_; // PlatformThread handle, reset after Join. |
120 WaitableEvent event_; // Signaled if Start() was ever called. | 125 WaitableEvent event_; // Signaled if Start() was ever called. |
121 PlatformThreadId tid_; // The backing thread's id. | 126 PlatformThreadId tid_ = kInvalidThreadId; // The backing thread's id. |
122 bool joined_; // True if Join has been called. | 127 bool joined_ = false; // True if Join has been called. |
| 128 |
| 129 DISALLOW_COPY_AND_ASSIGN(SimpleThread); |
123 }; | 130 }; |
124 | 131 |
| 132 // A SimpleThread which delegates Run() to its Delegate. The registered Delegate |
| 133 // must outlive its Run() invocation(s). As such, non-joinable |
| 134 // DelegateSimpleThread are safe to delete after Start() so long as the |
| 135 // Delegate's lifetime respects the aforementioned condition. |
125 class BASE_EXPORT DelegateSimpleThread : public SimpleThread { | 136 class BASE_EXPORT DelegateSimpleThread : public SimpleThread { |
126 public: | 137 public: |
127 class BASE_EXPORT Delegate { | 138 class BASE_EXPORT Delegate { |
128 public: | 139 public: |
129 Delegate() { } | 140 Delegate(); |
130 virtual ~Delegate() { } | 141 virtual ~Delegate(); |
| 142 |
| 143 // Invokes Run() and manages |active_runners_|. |
| 144 void RunHelper(); |
| 145 |
| 146 private: |
| 147 // Run() is private pure virtual because only RunHelper() should invoke it, |
| 148 // but it's still up to the implementer to define it. |
131 virtual void Run() = 0; | 149 virtual void Run() = 0; |
| 150 |
| 151 #if DCHECK_IS_ON() |
| 152 // Maintains a count of active Run() calls -- there can be more than one |
| 153 // when Delegate is used in a DelegateSimpleThreadPool. |
| 154 AtomicRefCount active_runners_ = 0; |
| 155 |
| 156 // Signaled when |active_runners_| is decremented, auto-reset after the |
| 157 // signal is observed. |
| 158 WaitableEvent active_runners_decremented_; |
| 159 #endif // DCHECK_IS_ON() |
| 160 |
| 161 DISALLOW_COPY_AND_ASSIGN(Delegate); |
132 }; | 162 }; |
133 | 163 |
134 DelegateSimpleThread(Delegate* delegate, | 164 DelegateSimpleThread(Delegate* delegate, |
135 const std::string& name_prefix); | 165 const std::string& name_prefix); |
136 DelegateSimpleThread(Delegate* delegate, | 166 DelegateSimpleThread(Delegate* delegate, |
137 const std::string& name_prefix, | 167 const std::string& name_prefix, |
138 const Options& options); | 168 const Options& options); |
139 | 169 |
140 ~DelegateSimpleThread() override; | 170 ~DelegateSimpleThread() override; |
141 void Run() override; | 171 void Run() override; |
142 | 172 |
143 private: | 173 private: |
144 Delegate* delegate_; | 174 Delegate* delegate_; |
| 175 |
| 176 #if DCHECK_IS_ON() |
| 177 bool ran_ = false; |
| 178 #endif |
| 179 |
| 180 DISALLOW_COPY_AND_ASSIGN(DelegateSimpleThread); |
145 }; | 181 }; |
146 | 182 |
147 // DelegateSimpleThreadPool allows you to start up a fixed number of threads, | 183 // DelegateSimpleThreadPool allows you to start up a fixed number of threads, |
148 // and then add jobs which will be dispatched to the threads. This is | 184 // and then add jobs which will be dispatched to the threads. This is |
149 // convenient when you have a lot of small work that you want done | 185 // convenient when you have a lot of small work that you want done |
150 // multi-threaded, but don't want to spawn a thread for each small bit of work. | 186 // multi-threaded, but don't want to spawn a thread for each small bit of work. |
151 // | 187 // |
152 // You just call AddWork() to add a delegate to the list of work to be done. | 188 // You just call AddWork() to add a delegate to the list of work to be done. |
153 // JoinAll() will make sure that all outstanding work is processed, and wait | 189 // JoinAll() will make sure that all outstanding work is processed, and wait |
154 // for everything to finish. You can reuse a pool, so you can call Start() | 190 // for everything to finish. You can reuse a pool, so you can call Start() |
(...skipping 24 matching lines...) Expand all Loading... |
179 // We implement the Delegate interface, for running our internal threads. | 215 // We implement the Delegate interface, for running our internal threads. |
180 void Run() override; | 216 void Run() override; |
181 | 217 |
182 private: | 218 private: |
183 const std::string name_prefix_; | 219 const std::string name_prefix_; |
184 int num_threads_; | 220 int num_threads_; |
185 std::vector<DelegateSimpleThread*> threads_; | 221 std::vector<DelegateSimpleThread*> threads_; |
186 std::queue<Delegate*> delegates_; | 222 std::queue<Delegate*> delegates_; |
187 base::Lock lock_; // Locks delegates_ | 223 base::Lock lock_; // Locks delegates_ |
188 WaitableEvent dry_; // Not signaled when there is no work to do. | 224 WaitableEvent dry_; // Not signaled when there is no work to do. |
| 225 |
| 226 DISALLOW_COPY_AND_ASSIGN(DelegateSimpleThreadPool); |
189 }; | 227 }; |
190 | 228 |
191 } // namespace base | 229 } // namespace base |
192 | 230 |
193 #endif // BASE_THREADING_SIMPLE_THREAD_H_ | 231 #endif // BASE_THREADING_SIMPLE_THREAD_H_ |
OLD | NEW |