blob: 72f15fde1cf8fbf3b8a3ab6531b58d4324f3c80b [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Henrik Kjellanderc0362762017-06-29 08:03:04 +020011#ifndef WEBRTC_RTC_BASE_THREAD_H_
12#define WEBRTC_RTC_BASE_THREAD_H_
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020014#include <algorithm>
15#include <list>
16#include <memory>
17#include <string>
18#include <vector>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000019
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020020#if defined(WEBRTC_POSIX)
21#include <pthread.h>
22#endif
kjellandere96c45b2017-06-30 10:45:21 -070023#include "webrtc/rtc_base/constructormagic.h"
24#include "webrtc/rtc_base/event.h"
25#include "webrtc/rtc_base/messagequeue.h"
26#include "webrtc/rtc_base/platform_thread_types.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020027
28#if defined(WEBRTC_WIN)
kjellandere96c45b2017-06-30 10:45:21 -070029#include "webrtc/rtc_base/win32.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020030#endif
31
32namespace rtc {
33
34class Thread;
35
36class 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
82struct _SendMessage {
83 _SendMessage() {}
84 Thread *thread;
85 Message msg;
86 bool *ready;
87};
88
89class 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
103class LOCKABLE Thread : public MessageQueue {
tommia8a35152017-07-13 05:47:25 -0700104 protected:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200105 Thread();
tommia8a35152017-07-13 05:47:25 -0700106
107 public:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200108 explicit Thread(SocketServer* ss);
109 explicit Thread(std::unique_ptr<SocketServer> ss);
110
111 // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or
112 // guarantee Stop() is explicitly called before the subclass is destroyed).
113 // This is required to avoid a data race between the destructor modifying the
114 // vtable, and the Thread::PreRun calling the virtual method Run().
115 ~Thread() override;
116
117 static std::unique_ptr<Thread> CreateWithSocketServer();
118 static std::unique_ptr<Thread> Create();
119 static Thread* Current();
120
121 // Used to catch performance regressions. Use this to disallow blocking calls
122 // (Invoke) for a given scope. If a synchronous call is made while this is in
123 // effect, an assert will be triggered.
124 // Note that this is a single threaded class.
125 class ScopedDisallowBlockingCalls {
126 public:
127 ScopedDisallowBlockingCalls();
128 ~ScopedDisallowBlockingCalls();
129 private:
130 Thread* const thread_;
131 const bool previous_state_;
132 };
133
134 bool IsCurrent() const;
135
136 // Sleeps the calling thread for the specified number of milliseconds, during
137 // which time no processing is performed. Returns false if sleeping was
138 // interrupted by a signal (POSIX only).
139 static bool SleepMs(int millis);
140
141 // Sets the thread's name, for debugging. Must be called before Start().
142 // If |obj| is non-null, its value is appended to |name|.
143 const std::string& name() const { return name_; }
144 bool SetName(const std::string& name, const void* obj);
145
146 // Starts the execution of the thread.
147 bool Start(Runnable* runnable = nullptr);
148
149 // Tells the thread to stop and waits until it is joined.
150 // Never call Stop on the current thread. Instead use the inherited Quit
151 // function which will exit the base MessageQueue without terminating the
152 // underlying OS thread.
153 virtual void Stop();
154
155 // By default, Thread::Run() calls ProcessMessages(kForever). To do other
156 // work, override Run(). To receive and dispatch messages, call
157 // ProcessMessages occasionally.
158 virtual void Run();
159
160 virtual void Send(const Location& posted_from,
161 MessageHandler* phandler,
162 uint32_t id = 0,
163 MessageData* pdata = nullptr);
164
165 // Convenience method to invoke a functor on another thread. Caller must
166 // provide the |ReturnT| template argument, which cannot (easily) be deduced.
167 // Uses Send() internally, which blocks the current thread until execution
168 // is complete.
169 // Ex: bool result = thread.Invoke<bool>(RTC_FROM_HERE,
170 // &MyFunctionReturningBool);
171 // NOTE: This function can only be called when synchronous calls are allowed.
172 // See ScopedDisallowBlockingCalls for details.
173 template <class ReturnT, class FunctorT>
174 ReturnT Invoke(const Location& posted_from, const FunctorT& functor) {
175 FunctorMessageHandler<ReturnT, FunctorT> handler(functor);
176 InvokeInternal(posted_from, &handler);
177 return handler.MoveResult();
178 }
179
180 // From MessageQueue
181 void Clear(MessageHandler* phandler,
182 uint32_t id = MQID_ANY,
183 MessageList* removed = nullptr) override;
184 void ReceiveSends() override;
185
186 // ProcessMessages will process I/O and dispatch messages until:
187 // 1) cms milliseconds have elapsed (returns true)
188 // 2) Stop() is called (returns false)
189 bool ProcessMessages(int cms);
190
191 // Returns true if this is a thread that we created using the standard
192 // constructor, false if it was created by a call to
193 // ThreadManager::WrapCurrentThread(). The main thread of an application
194 // is generally not owned, since the OS representation of the thread
195 // obviously exists before we can get to it.
196 // You cannot call Start on non-owned threads.
197 bool IsOwned();
198
199#if defined(WEBRTC_WIN)
200 HANDLE GetHandle() const {
201 return thread_;
202 }
203 DWORD GetId() const {
204 return thread_id_;
205 }
206#elif defined(WEBRTC_POSIX)
207 pthread_t GetPThread() {
208 return thread_;
209 }
210#endif
211
212 // Expose private method running() for tests.
213 //
214 // DANGER: this is a terrible public API. Most callers that might want to
215 // call this likely do not have enough control/knowledge of the Thread in
216 // question to guarantee that the returned value remains true for the duration
217 // of whatever code is conditionally executing because of the return value!
218 bool RunningForTest() { return running(); }
219
220 // Sets the per-thread allow-blocking-calls flag and returns the previous
221 // value. Must be called on this thread.
222 bool SetAllowBlockingCalls(bool allow);
223
224 // These functions are public to avoid injecting test hooks. Don't call them
225 // outside of tests.
226 // This method should be called when thread is created using non standard
227 // method, like derived implementation of rtc::Thread and it can not be
228 // started by calling Start(). This will set started flag to true and
229 // owned to false. This must be called from the current thread.
230 bool WrapCurrent();
231 void UnwrapCurrent();
232
233 protected:
234 // Same as WrapCurrent except that it never fails as it does not try to
235 // acquire the synchronization access of the thread. The caller should never
236 // call Stop() or Join() on this thread.
237 void SafeWrapCurrent();
238
239 // Blocks the calling thread until this thread has terminated.
240 void Join();
241
242 static void AssertBlockingIsAllowedOnCurrentThread();
243
244 friend class ScopedDisallowBlockingCalls;
245
246 private:
247 struct ThreadInit {
248 Thread* thread;
249 Runnable* runnable;
250 };
251
252#if defined(WEBRTC_WIN)
253 static DWORD WINAPI PreRun(LPVOID context);
254#else
255 static void *PreRun(void *pv);
256#endif
257
258 // ThreadManager calls this instead WrapCurrent() because
259 // ThreadManager::Instance() cannot be used while ThreadManager is
260 // being created.
261 // The method tries to get synchronization rights of the thread on Windows if
262 // |need_synchronize_access| is true.
263 bool WrapCurrentWithThreadManager(ThreadManager* thread_manager,
264 bool need_synchronize_access);
265
266 // Return true if the thread was started and hasn't yet stopped.
267 bool running() { return running_.Wait(0); }
268
269 // Processes received "Send" requests. If |source| is not null, only requests
270 // from |source| are processed, otherwise, all requests are processed.
271 void ReceiveSendsFromThread(const Thread* source);
272
273 // If |source| is not null, pops the first "Send" message from |source| in
274 // |sendlist_|, otherwise, pops the first "Send" message of |sendlist_|.
275 // The caller must lock |crit_| before calling.
276 // Returns true if there is such a message.
277 bool PopSendMessageFromThread(const Thread* source, _SendMessage* msg);
278
279 void InvokeInternal(const Location& posted_from, MessageHandler* handler);
280
281 std::list<_SendMessage> sendlist_;
282 std::string name_;
283 Event running_; // Signalled means running.
284
285#if defined(WEBRTC_POSIX)
286 pthread_t thread_;
287#endif
288
289#if defined(WEBRTC_WIN)
290 HANDLE thread_;
291 DWORD thread_id_;
292#endif
293
294 bool owned_;
295 bool blocking_calls_allowed_; // By default set to |true|.
296
297 friend class ThreadManager;
298
299 RTC_DISALLOW_COPY_AND_ASSIGN(Thread);
300};
301
302// AutoThread automatically installs itself at construction
303// uninstalls at destruction, if a Thread object is
304// _not already_ associated with the current OS thread.
305
306class AutoThread : public Thread {
307 public:
308 AutoThread();
309 ~AutoThread() override;
310
311 private:
312 RTC_DISALLOW_COPY_AND_ASSIGN(AutoThread);
313};
314
315// AutoSocketServerThread automatically installs itself at
316// construction and uninstalls at destruction. If a Thread object is
317// already associated with the current OS thread, it is temporarily
318// disassociated and restored by the destructor.
319
320class AutoSocketServerThread : public Thread {
321 public:
322 explicit AutoSocketServerThread(SocketServer* ss);
323 ~AutoSocketServerThread() override;
324
325 private:
326 rtc::Thread* old_thread_;
327
328 RTC_DISALLOW_COPY_AND_ASSIGN(AutoSocketServerThread);
329};
330
331} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000332
Henrik Kjellanderc0362762017-06-29 08:03:04 +0200333#endif // WEBRTC_RTC_BASE_THREAD_H_