blob: 58df2536b12c0126b161a9a4224f4f7bf2233861 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef RTC_BASE_THREAD_H_
12#define RTC_BASE_THREAD_H_
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013
Yves Gerey988cc082018-10-23 12:03:01 +020014#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020015
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020016#include <list>
17#include <memory>
18#include <string>
Yves Gerey988cc082018-10-23 12:03:01 +020019#include <type_traits>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000020
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020021#if defined(WEBRTC_POSIX)
22#include <pthread.h>
23#endif
Steve Anton10542f22019-01-11 09:11:00 -080024#include "rtc_base/constructor_magic.h"
Yves Gerey988cc082018-10-23 12:03:01 +020025#include "rtc_base/location.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "rtc_base/message_handler.h"
27#include "rtc_base/message_queue.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "rtc_base/platform_thread_types.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/socket_server.h"
Yves Gerey988cc082018-10-23 12:03:01 +020030#include "rtc_base/thread_annotations.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020031
32#if defined(WEBRTC_WIN)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "rtc_base/win32.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020034#endif
35
36namespace rtc {
37
38class Thread;
39
Henrik Boströmba4dcc32019-02-28 09:34:06 +010040namespace rtc_thread_internal {
41
Niels Möllerf13a0962019-05-17 10:15:06 +020042class MessageLikeTask : public MessageData {
Henrik Boströmba4dcc32019-02-28 09:34:06 +010043 public:
Niels Möllerf13a0962019-05-17 10:15:06 +020044 virtual void Run() = 0;
45};
46
47template <class FunctorT>
48class MessageWithFunctor final : public MessageLikeTask {
49 public:
50 explicit MessageWithFunctor(FunctorT&& functor)
Henrik Boströmba4dcc32019-02-28 09:34:06 +010051 : functor_(std::forward<FunctorT>(functor)) {}
52
Niels Möllerf13a0962019-05-17 10:15:06 +020053 void Run() override { functor_(); }
Henrik Boströmba4dcc32019-02-28 09:34:06 +010054
55 private:
Niels Möllerf13a0962019-05-17 10:15:06 +020056 ~MessageWithFunctor() override {}
Henrik Boströmba4dcc32019-02-28 09:34:06 +010057
58 typename std::remove_reference<FunctorT>::type functor_;
59
Niels Möllerf13a0962019-05-17 10:15:06 +020060 RTC_DISALLOW_COPY_AND_ASSIGN(MessageWithFunctor);
61};
62
63class MessageHandlerWithTask final : public MessageHandler {
64 public:
65 MessageHandlerWithTask() = default;
66
67 void OnMessage(Message* msg) override {
68 static_cast<MessageLikeTask*>(msg->pdata)->Run();
69 delete msg->pdata;
70 }
71
72 private:
73 ~MessageHandlerWithTask() override {}
74
75 RTC_DISALLOW_COPY_AND_ASSIGN(MessageHandlerWithTask);
Henrik Boströmba4dcc32019-02-28 09:34:06 +010076};
77
78} // namespace rtc_thread_internal
79
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020080class ThreadManager {
81 public:
82 static const int kForever = -1;
83
84 // Singleton, constructor and destructor are private.
85 static ThreadManager* Instance();
86
87 Thread* CurrentThread();
88 void SetCurrentThread(Thread* thread);
89
90 // Returns a thread object with its thread_ ivar set
91 // to whatever the OS uses to represent the thread.
92 // If there already *is* a Thread object corresponding to this thread,
93 // this method will return that. Otherwise it creates a new Thread
94 // object whose wrapped() method will return true, and whose
95 // handle will, on Win32, be opened with only synchronization privileges -
96 // if you need more privilegs, rather than changing this method, please
97 // write additional code to adjust the privileges, or call a different
98 // factory method of your own devising, because this one gets used in
99 // unexpected contexts (like inside browser plugins) and it would be a
100 // shame to break it. It is also conceivable on Win32 that we won't even
101 // be able to get synchronization privileges, in which case the result
102 // will have a null handle.
Yves Gerey665174f2018-06-19 15:03:05 +0200103 Thread* WrapCurrentThread();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200104 void UnwrapCurrentThread();
105
Niels Moller9d1840c2019-05-21 07:26:37 +0000106 bool IsMainThread();
107
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200108 private:
109 ThreadManager();
110 ~ThreadManager();
111
112#if defined(WEBRTC_POSIX)
113 pthread_key_t key_;
114#endif
115
116#if defined(WEBRTC_WIN)
Tommi51492422017-12-04 15:18:23 +0100117 const DWORD key_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200118#endif
119
Niels Moller9d1840c2019-05-21 07:26:37 +0000120 // The thread to potentially autowrap.
121 const PlatformThreadRef main_thread_ref_;
122
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200123 RTC_DISALLOW_COPY_AND_ASSIGN(ThreadManager);
124};
125
126struct _SendMessage {
127 _SendMessage() {}
Yves Gerey665174f2018-06-19 15:03:05 +0200128 Thread* thread;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200129 Message msg;
Yves Gerey665174f2018-06-19 15:03:05 +0200130 bool* ready;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200131};
132
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200133// WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread().
134
danilchap3c6abd22017-09-06 05:46:29 -0700135class RTC_LOCKABLE Thread : public MessageQueue {
tommia8a35152017-07-13 05:47:25 -0700136 public:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200137 explicit Thread(SocketServer* ss);
138 explicit Thread(std::unique_ptr<SocketServer> ss);
Taylor Brandstetter08672602018-03-02 15:20:33 -0800139 // Constructors meant for subclasses; they should call DoInit themselves and
140 // pass false for |do_init|, so that DoInit is called only on the fully
141 // instantiated class, which avoids a vptr data race.
142 Thread(SocketServer* ss, bool do_init);
143 Thread(std::unique_ptr<SocketServer> ss, bool do_init);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200144
145 // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or
146 // guarantee Stop() is explicitly called before the subclass is destroyed).
147 // This is required to avoid a data race between the destructor modifying the
148 // vtable, and the Thread::PreRun calling the virtual method Run().
149 ~Thread() override;
150
151 static std::unique_ptr<Thread> CreateWithSocketServer();
152 static std::unique_ptr<Thread> Create();
153 static Thread* Current();
154
155 // Used to catch performance regressions. Use this to disallow blocking calls
156 // (Invoke) for a given scope. If a synchronous call is made while this is in
157 // effect, an assert will be triggered.
158 // Note that this is a single threaded class.
159 class ScopedDisallowBlockingCalls {
160 public:
161 ScopedDisallowBlockingCalls();
Sebastian Jansson9debe5a2019-03-22 15:42:38 +0100162 ScopedDisallowBlockingCalls(const ScopedDisallowBlockingCalls&) = delete;
163 ScopedDisallowBlockingCalls& operator=(const ScopedDisallowBlockingCalls&) =
164 delete;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200165 ~ScopedDisallowBlockingCalls();
Yves Gerey665174f2018-06-19 15:03:05 +0200166
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200167 private:
168 Thread* const thread_;
169 const bool previous_state_;
170 };
171
172 bool IsCurrent() const;
173
174 // Sleeps the calling thread for the specified number of milliseconds, during
175 // which time no processing is performed. Returns false if sleeping was
176 // interrupted by a signal (POSIX only).
177 static bool SleepMs(int millis);
178
179 // Sets the thread's name, for debugging. Must be called before Start().
180 // If |obj| is non-null, its value is appended to |name|.
181 const std::string& name() const { return name_; }
182 bool SetName(const std::string& name, const void* obj);
183
184 // Starts the execution of the thread.
Niels Möllerd2e50132019-06-11 09:24:14 +0200185 bool Start();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200186
187 // Tells the thread to stop and waits until it is joined.
188 // Never call Stop on the current thread. Instead use the inherited Quit
189 // function which will exit the base MessageQueue without terminating the
190 // underlying OS thread.
191 virtual void Stop();
192
193 // By default, Thread::Run() calls ProcessMessages(kForever). To do other
194 // work, override Run(). To receive and dispatch messages, call
195 // ProcessMessages occasionally.
196 virtual void Run();
197
198 virtual void Send(const Location& posted_from,
199 MessageHandler* phandler,
200 uint32_t id = 0,
201 MessageData* pdata = nullptr);
202
203 // Convenience method to invoke a functor on another thread. Caller must
204 // provide the |ReturnT| template argument, which cannot (easily) be deduced.
205 // Uses Send() internally, which blocks the current thread until execution
206 // is complete.
207 // Ex: bool result = thread.Invoke<bool>(RTC_FROM_HERE,
208 // &MyFunctionReturningBool);
209 // NOTE: This function can only be called when synchronous calls are allowed.
210 // See ScopedDisallowBlockingCalls for details.
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100211 // NOTE: Blocking invokes are DISCOURAGED, consider if what you're doing can
212 // be achieved with PostTask() and callbacks instead.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200213 template <class ReturnT, class FunctorT>
Karl Wibergd6b48192017-10-16 23:01:06 +0200214 ReturnT Invoke(const Location& posted_from, FunctorT&& functor) {
215 FunctorMessageHandler<ReturnT, FunctorT> handler(
216 std::forward<FunctorT>(functor));
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200217 InvokeInternal(posted_from, &handler);
218 return handler.MoveResult();
219 }
220
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100221 // Posts a task to invoke the functor on |this| thread asynchronously, i.e.
222 // without blocking the thread that invoked PostTask(). Ownership of |functor|
Niels Möllerf13a0962019-05-17 10:15:06 +0200223 // is passed and (usually, see below) destroyed on |this| thread after it is
224 // invoked.
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100225 // Requirements of FunctorT:
226 // - FunctorT is movable.
227 // - FunctorT implements "T operator()()" or "T operator()() const" for some T
228 // (if T is not void, the return value is discarded on |this| thread).
229 // - FunctorT has a public destructor that can be invoked from |this| thread
230 // after operation() has been invoked.
231 // - The functor must not cause the thread to quit before PostTask() is done.
232 //
Niels Möllerf13a0962019-05-17 10:15:06 +0200233 // Destruction of the functor/task mimics what TaskQueue::PostTask does: If
234 // the task is run, it will be destroyed on |this| thread. However, if there
235 // are pending tasks by the time the Thread is destroyed, or a task is posted
236 // to a thread that is quitting, the task is destroyed immediately, on the
237 // calling thread. Destroying the Thread only blocks for any currently running
238 // task to complete. Note that TQ abstraction is even vaguer on how
239 // destruction happens in these cases, allowing destruction to happen
240 // asynchronously at a later time and on some arbitrary thread. So to ease
241 // migration, don't depend on Thread::PostTask destroying un-run tasks
242 // immediately.
243 //
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100244 // Example - Calling a class method:
245 // class Foo {
246 // public:
247 // void DoTheThing();
248 // };
249 // Foo foo;
250 // thread->PostTask(RTC_FROM_HERE, Bind(&Foo::DoTheThing, &foo));
251 //
252 // Example - Calling a lambda function:
253 // thread->PostTask(RTC_FROM_HERE,
254 // [&x, &y] { x.TrackComputations(y.Compute()); });
255 template <class FunctorT>
256 void PostTask(const Location& posted_from, FunctorT&& functor) {
Niels Möllerf13a0962019-05-17 10:15:06 +0200257 // Allocate at first call, never deallocate.
258 static auto* const handler =
259 new rtc_thread_internal::MessageHandlerWithTask;
260 Post(posted_from, handler, 0,
261 new rtc_thread_internal::MessageWithFunctor<FunctorT>(
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100262 std::forward<FunctorT>(functor)));
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100263 }
264
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200265 // From MessageQueue
Niels Möller8909a632018-09-06 08:42:44 +0200266 bool IsProcessingMessagesForTesting() override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200267 void Clear(MessageHandler* phandler,
268 uint32_t id = MQID_ANY,
269 MessageList* removed = nullptr) override;
270 void ReceiveSends() override;
271
272 // ProcessMessages will process I/O and dispatch messages until:
273 // 1) cms milliseconds have elapsed (returns true)
274 // 2) Stop() is called (returns false)
275 bool ProcessMessages(int cms);
276
277 // Returns true if this is a thread that we created using the standard
278 // constructor, false if it was created by a call to
279 // ThreadManager::WrapCurrentThread(). The main thread of an application
280 // is generally not owned, since the OS representation of the thread
281 // obviously exists before we can get to it.
282 // You cannot call Start on non-owned threads.
283 bool IsOwned();
284
Tommi51492422017-12-04 15:18:23 +0100285 // Expose private method IsRunning() for tests.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200286 //
287 // DANGER: this is a terrible public API. Most callers that might want to
288 // call this likely do not have enough control/knowledge of the Thread in
289 // question to guarantee that the returned value remains true for the duration
290 // of whatever code is conditionally executing because of the return value!
Tommi51492422017-12-04 15:18:23 +0100291 bool RunningForTest() { return IsRunning(); }
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200292
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200293 // These functions are public to avoid injecting test hooks. Don't call them
294 // outside of tests.
295 // This method should be called when thread is created using non standard
296 // method, like derived implementation of rtc::Thread and it can not be
297 // started by calling Start(). This will set started flag to true and
298 // owned to false. This must be called from the current thread.
299 bool WrapCurrent();
300 void UnwrapCurrent();
301
Karl Wiberg32562252019-02-21 13:38:30 +0100302 // Sets the per-thread allow-blocking-calls flag to false; this is
303 // irrevocable. Must be called on this thread.
304 void DisallowBlockingCalls() { SetAllowBlockingCalls(false); }
305
306#ifdef WEBRTC_ANDROID
307 // Sets the per-thread allow-blocking-calls flag to true, sidestepping the
308 // invariants upheld by DisallowBlockingCalls() and
309 // ScopedDisallowBlockingCalls. Must be called on this thread.
310 void DEPRECATED_AllowBlockingCalls() { SetAllowBlockingCalls(true); }
311#endif
312
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200313 protected:
314 // Same as WrapCurrent except that it never fails as it does not try to
315 // acquire the synchronization access of the thread. The caller should never
316 // call Stop() or Join() on this thread.
317 void SafeWrapCurrent();
318
319 // Blocks the calling thread until this thread has terminated.
320 void Join();
321
322 static void AssertBlockingIsAllowedOnCurrentThread();
323
324 friend class ScopedDisallowBlockingCalls;
325
326 private:
Karl Wiberg32562252019-02-21 13:38:30 +0100327 // Sets the per-thread allow-blocking-calls flag and returns the previous
328 // value. Must be called on this thread.
329 bool SetAllowBlockingCalls(bool allow);
330
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200331#if defined(WEBRTC_WIN)
332 static DWORD WINAPI PreRun(LPVOID context);
333#else
Yves Gerey665174f2018-06-19 15:03:05 +0200334 static void* PreRun(void* pv);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200335#endif
336
337 // ThreadManager calls this instead WrapCurrent() because
338 // ThreadManager::Instance() cannot be used while ThreadManager is
339 // being created.
340 // The method tries to get synchronization rights of the thread on Windows if
341 // |need_synchronize_access| is true.
342 bool WrapCurrentWithThreadManager(ThreadManager* thread_manager,
343 bool need_synchronize_access);
344
Tommi51492422017-12-04 15:18:23 +0100345 // Return true if the thread is currently running.
346 bool IsRunning();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200347
348 // Processes received "Send" requests. If |source| is not null, only requests
349 // from |source| are processed, otherwise, all requests are processed.
350 void ReceiveSendsFromThread(const Thread* source);
351
352 // If |source| is not null, pops the first "Send" message from |source| in
353 // |sendlist_|, otherwise, pops the first "Send" message of |sendlist_|.
354 // The caller must lock |crit_| before calling.
355 // Returns true if there is such a message.
356 bool PopSendMessageFromThread(const Thread* source, _SendMessage* msg);
357
358 void InvokeInternal(const Location& posted_from, MessageHandler* handler);
359
360 std::list<_SendMessage> sendlist_;
361 std::string name_;
Tommi51492422017-12-04 15:18:23 +0100362
Jonas Olssona4d87372019-07-05 19:08:33 +0200363 // TODO(tommi): Add thread checks for proper use of control methods.
364 // Ideally we should be able to just use PlatformThread.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200365
366#if defined(WEBRTC_POSIX)
Tommi6cea2b02017-12-04 18:51:16 +0100367 pthread_t thread_ = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200368#endif
369
370#if defined(WEBRTC_WIN)
Tommi6cea2b02017-12-04 18:51:16 +0100371 HANDLE thread_ = nullptr;
372 DWORD thread_id_ = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200373#endif
374
Tommi51492422017-12-04 15:18:23 +0100375 // Indicates whether or not ownership of the worker thread lies with
376 // this instance or not. (i.e. owned_ == !wrapped).
377 // Must only be modified when the worker thread is not running.
378 bool owned_ = true;
379
380 // Only touched from the worker thread itself.
381 bool blocking_calls_allowed_ = true;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200382
383 friend class ThreadManager;
384
385 RTC_DISALLOW_COPY_AND_ASSIGN(Thread);
386};
387
388// AutoThread automatically installs itself at construction
389// uninstalls at destruction, if a Thread object is
390// _not already_ associated with the current OS thread.
391
392class AutoThread : public Thread {
393 public:
394 AutoThread();
395 ~AutoThread() override;
396
397 private:
398 RTC_DISALLOW_COPY_AND_ASSIGN(AutoThread);
399};
400
401// AutoSocketServerThread automatically installs itself at
402// construction and uninstalls at destruction. If a Thread object is
403// already associated with the current OS thread, it is temporarily
404// disassociated and restored by the destructor.
405
406class AutoSocketServerThread : public Thread {
407 public:
408 explicit AutoSocketServerThread(SocketServer* ss);
409 ~AutoSocketServerThread() override;
410
411 private:
412 rtc::Thread* old_thread_;
413
414 RTC_DISALLOW_COPY_AND_ASSIGN(AutoSocketServerThread);
415};
416
417} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000418
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200419#endif // RTC_BASE_THREAD_H_