OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_BASE_THREAD_H_ | 11 #ifndef WEBRTC_BASE_THREAD_H_ |
12 #define WEBRTC_BASE_THREAD_H_ | 12 #define WEBRTC_BASE_THREAD_H_ |
13 | 13 |
14 #include <algorithm> | |
15 #include <list> | |
16 #include <memory> | |
17 #include <string> | |
18 #include <vector> | |
19 | 14 |
20 #if defined(WEBRTC_POSIX) | 15 // This header is deprecated and is just left here temporarily during |
21 #include <pthread.h> | 16 // refactoring. See https://bugs.webrtc.org/7634 for more details. |
22 #endif | 17 #include "webrtc/rtc_base/thread.h" |
23 #include "webrtc/base/constructormagic.h" | |
24 #include "webrtc/base/event.h" | |
25 #include "webrtc/base/messagequeue.h" | |
26 #include "webrtc/base/platform_thread_types.h" | |
27 | |
28 #if defined(WEBRTC_WIN) | |
29 #include "webrtc/base/win32.h" | |
30 #endif | |
31 | |
32 namespace rtc { | |
33 | |
34 class Thread; | |
35 | |
36 class ThreadManager { | |
37 public: | |
38 static const int kForever = -1; | |
39 | |
40 // Singleton, constructor and destructor are private. | |
41 static ThreadManager* Instance(); | |
42 | |
43 Thread* CurrentThread(); | |
44 void SetCurrentThread(Thread* thread); | |
45 | |
46 // Returns a thread object with its thread_ ivar set | |
47 // to whatever the OS uses to represent the thread. | |
48 // If there already *is* a Thread object corresponding to this thread, | |
49 // this method will return that. Otherwise it creates a new Thread | |
50 // object whose wrapped() method will return true, and whose | |
51 // handle will, on Win32, be opened with only synchronization privileges - | |
52 // if you need more privilegs, rather than changing this method, please | |
53 // write additional code to adjust the privileges, or call a different | |
54 // factory method of your own devising, because this one gets used in | |
55 // unexpected contexts (like inside browser plugins) and it would be a | |
56 // shame to break it. It is also conceivable on Win32 that we won't even | |
57 // be able to get synchronization privileges, in which case the result | |
58 // will have a null handle. | |
59 Thread *WrapCurrentThread(); | |
60 void UnwrapCurrentThread(); | |
61 | |
62 bool IsMainThread(); | |
63 | |
64 private: | |
65 ThreadManager(); | |
66 ~ThreadManager(); | |
67 | |
68 #if defined(WEBRTC_POSIX) | |
69 pthread_key_t key_; | |
70 #endif | |
71 | |
72 #if defined(WEBRTC_WIN) | |
73 DWORD key_; | |
74 #endif | |
75 | |
76 // The thread to potentially autowrap. | |
77 PlatformThreadRef main_thread_ref_; | |
78 | |
79 RTC_DISALLOW_COPY_AND_ASSIGN(ThreadManager); | |
80 }; | |
81 | |
82 struct _SendMessage { | |
83 _SendMessage() {} | |
84 Thread *thread; | |
85 Message msg; | |
86 bool *ready; | |
87 }; | |
88 | |
89 class Runnable { | |
90 public: | |
91 virtual ~Runnable() {} | |
92 virtual void Run(Thread* thread) = 0; | |
93 | |
94 protected: | |
95 Runnable() {} | |
96 | |
97 private: | |
98 RTC_DISALLOW_COPY_AND_ASSIGN(Runnable); | |
99 }; | |
100 | |
101 // WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread(). | |
102 | |
103 class LOCKABLE Thread : public MessageQueue { | |
104 public: | |
105 // Create a new Thread and optionally assign it to the passed SocketServer. | |
106 Thread(); | |
107 explicit Thread(SocketServer* ss); | |
108 explicit Thread(std::unique_ptr<SocketServer> ss); | |
109 | |
110 // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or | |
111 // guarantee Stop() is explicitly called before the subclass is destroyed). | |
112 // This is required to avoid a data race between the destructor modifying the | |
113 // vtable, and the Thread::PreRun calling the virtual method Run(). | |
114 ~Thread() override; | |
115 | |
116 static std::unique_ptr<Thread> CreateWithSocketServer(); | |
117 static std::unique_ptr<Thread> Create(); | |
118 static Thread* Current(); | |
119 | |
120 // Used to catch performance regressions. Use this to disallow blocking calls | |
121 // (Invoke) for a given scope. If a synchronous call is made while this is in | |
122 // effect, an assert will be triggered. | |
123 // Note that this is a single threaded class. | |
124 class ScopedDisallowBlockingCalls { | |
125 public: | |
126 ScopedDisallowBlockingCalls(); | |
127 ~ScopedDisallowBlockingCalls(); | |
128 private: | |
129 Thread* const thread_; | |
130 const bool previous_state_; | |
131 }; | |
132 | |
133 bool IsCurrent() const; | |
134 | |
135 // Sleeps the calling thread for the specified number of milliseconds, during | |
136 // which time no processing is performed. Returns false if sleeping was | |
137 // interrupted by a signal (POSIX only). | |
138 static bool SleepMs(int millis); | |
139 | |
140 // Sets the thread's name, for debugging. Must be called before Start(). | |
141 // If |obj| is non-null, its value is appended to |name|. | |
142 const std::string& name() const { return name_; } | |
143 bool SetName(const std::string& name, const void* obj); | |
144 | |
145 // Starts the execution of the thread. | |
146 bool Start(Runnable* runnable = nullptr); | |
147 | |
148 // Tells the thread to stop and waits until it is joined. | |
149 // Never call Stop on the current thread. Instead use the inherited Quit | |
150 // function which will exit the base MessageQueue without terminating the | |
151 // underlying OS thread. | |
152 virtual void Stop(); | |
153 | |
154 // By default, Thread::Run() calls ProcessMessages(kForever). To do other | |
155 // work, override Run(). To receive and dispatch messages, call | |
156 // ProcessMessages occasionally. | |
157 virtual void Run(); | |
158 | |
159 virtual void Send(const Location& posted_from, | |
160 MessageHandler* phandler, | |
161 uint32_t id = 0, | |
162 MessageData* pdata = nullptr); | |
163 | |
164 // Convenience method to invoke a functor on another thread. Caller must | |
165 // provide the |ReturnT| template argument, which cannot (easily) be deduced. | |
166 // Uses Send() internally, which blocks the current thread until execution | |
167 // is complete. | |
168 // Ex: bool result = thread.Invoke<bool>(RTC_FROM_HERE, | |
169 // &MyFunctionReturningBool); | |
170 // NOTE: This function can only be called when synchronous calls are allowed. | |
171 // See ScopedDisallowBlockingCalls for details. | |
172 template <class ReturnT, class FunctorT> | |
173 ReturnT Invoke(const Location& posted_from, const FunctorT& functor) { | |
174 FunctorMessageHandler<ReturnT, FunctorT> handler(functor); | |
175 InvokeInternal(posted_from, &handler); | |
176 return handler.MoveResult(); | |
177 } | |
178 | |
179 // From MessageQueue | |
180 void Clear(MessageHandler* phandler, | |
181 uint32_t id = MQID_ANY, | |
182 MessageList* removed = nullptr) override; | |
183 void ReceiveSends() override; | |
184 | |
185 // ProcessMessages will process I/O and dispatch messages until: | |
186 // 1) cms milliseconds have elapsed (returns true) | |
187 // 2) Stop() is called (returns false) | |
188 bool ProcessMessages(int cms); | |
189 | |
190 // Returns true if this is a thread that we created using the standard | |
191 // constructor, false if it was created by a call to | |
192 // ThreadManager::WrapCurrentThread(). The main thread of an application | |
193 // is generally not owned, since the OS representation of the thread | |
194 // obviously exists before we can get to it. | |
195 // You cannot call Start on non-owned threads. | |
196 bool IsOwned(); | |
197 | |
198 #if defined(WEBRTC_WIN) | |
199 HANDLE GetHandle() const { | |
200 return thread_; | |
201 } | |
202 DWORD GetId() const { | |
203 return thread_id_; | |
204 } | |
205 #elif defined(WEBRTC_POSIX) | |
206 pthread_t GetPThread() { | |
207 return thread_; | |
208 } | |
209 #endif | |
210 | |
211 // Expose private method running() for tests. | |
212 // | |
213 // DANGER: this is a terrible public API. Most callers that might want to | |
214 // call this likely do not have enough control/knowledge of the Thread in | |
215 // question to guarantee that the returned value remains true for the duration | |
216 // of whatever code is conditionally executing because of the return value! | |
217 bool RunningForTest() { return running(); } | |
218 | |
219 // Sets the per-thread allow-blocking-calls flag and returns the previous | |
220 // value. Must be called on this thread. | |
221 bool SetAllowBlockingCalls(bool allow); | |
222 | |
223 // These functions are public to avoid injecting test hooks. Don't call them | |
224 // outside of tests. | |
225 // This method should be called when thread is created using non standard | |
226 // method, like derived implementation of rtc::Thread and it can not be | |
227 // started by calling Start(). This will set started flag to true and | |
228 // owned to false. This must be called from the current thread. | |
229 bool WrapCurrent(); | |
230 void UnwrapCurrent(); | |
231 | |
232 protected: | |
233 // Same as WrapCurrent except that it never fails as it does not try to | |
234 // acquire the synchronization access of the thread. The caller should never | |
235 // call Stop() or Join() on this thread. | |
236 void SafeWrapCurrent(); | |
237 | |
238 // Blocks the calling thread until this thread has terminated. | |
239 void Join(); | |
240 | |
241 static void AssertBlockingIsAllowedOnCurrentThread(); | |
242 | |
243 friend class ScopedDisallowBlockingCalls; | |
244 | |
245 private: | |
246 struct ThreadInit { | |
247 Thread* thread; | |
248 Runnable* runnable; | |
249 }; | |
250 | |
251 #if defined(WEBRTC_WIN) | |
252 static DWORD WINAPI PreRun(LPVOID context); | |
253 #else | |
254 static void *PreRun(void *pv); | |
255 #endif | |
256 | |
257 // ThreadManager calls this instead WrapCurrent() because | |
258 // ThreadManager::Instance() cannot be used while ThreadManager is | |
259 // being created. | |
260 // The method tries to get synchronization rights of the thread on Windows if | |
261 // |need_synchronize_access| is true. | |
262 bool WrapCurrentWithThreadManager(ThreadManager* thread_manager, | |
263 bool need_synchronize_access); | |
264 | |
265 // Return true if the thread was started and hasn't yet stopped. | |
266 bool running() { return running_.Wait(0); } | |
267 | |
268 // Processes received "Send" requests. If |source| is not null, only requests | |
269 // from |source| are processed, otherwise, all requests are processed. | |
270 void ReceiveSendsFromThread(const Thread* source); | |
271 | |
272 // If |source| is not null, pops the first "Send" message from |source| in | |
273 // |sendlist_|, otherwise, pops the first "Send" message of |sendlist_|. | |
274 // The caller must lock |crit_| before calling. | |
275 // Returns true if there is such a message. | |
276 bool PopSendMessageFromThread(const Thread* source, _SendMessage* msg); | |
277 | |
278 void InvokeInternal(const Location& posted_from, MessageHandler* handler); | |
279 | |
280 std::list<_SendMessage> sendlist_; | |
281 std::string name_; | |
282 Event running_; // Signalled means running. | |
283 | |
284 #if defined(WEBRTC_POSIX) | |
285 pthread_t thread_; | |
286 #endif | |
287 | |
288 #if defined(WEBRTC_WIN) | |
289 HANDLE thread_; | |
290 DWORD thread_id_; | |
291 #endif | |
292 | |
293 bool owned_; | |
294 bool blocking_calls_allowed_; // By default set to |true|. | |
295 | |
296 friend class ThreadManager; | |
297 | |
298 RTC_DISALLOW_COPY_AND_ASSIGN(Thread); | |
299 }; | |
300 | |
301 // AutoThread automatically installs itself at construction | |
302 // uninstalls at destruction, if a Thread object is | |
303 // _not already_ associated with the current OS thread. | |
304 | |
305 class AutoThread : public Thread { | |
306 public: | |
307 AutoThread(); | |
308 ~AutoThread() override; | |
309 | |
310 private: | |
311 RTC_DISALLOW_COPY_AND_ASSIGN(AutoThread); | |
312 }; | |
313 | |
314 // AutoSocketServerThread automatically installs itself at | |
315 // construction and uninstalls at destruction. If a Thread object is | |
316 // already associated with the current OS thread, it is temporarily | |
317 // disassociated and restored by the destructor. | |
318 | |
319 class AutoSocketServerThread : public Thread { | |
320 public: | |
321 explicit AutoSocketServerThread(SocketServer* ss); | |
322 ~AutoSocketServerThread() override; | |
323 | |
324 private: | |
325 rtc::Thread* old_thread_; | |
326 | |
327 RTC_DISALLOW_COPY_AND_ASSIGN(AutoSocketServerThread); | |
328 }; | |
329 | |
330 } // namespace rtc | |
331 | 18 |
332 #endif // WEBRTC_BASE_THREAD_H_ | 19 #endif // WEBRTC_BASE_THREAD_H_ |
OLD | NEW |