blob: 80720e079421282a71bcd528211ee82521fdf9c5 [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>
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020015#include <list>
16#include <memory>
17#include <string>
Yves Gerey988cc082018-10-23 12:03:01 +020018#include <type_traits>
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
Steve Anton10542f22019-01-11 09:11:00 -080023#include "rtc_base/constructor_magic.h"
Yves Gerey988cc082018-10-23 12:03:01 +020024#include "rtc_base/location.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "rtc_base/message_handler.h"
26#include "rtc_base/message_queue.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "rtc_base/platform_thread_types.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/socket_server.h"
Yves Gerey988cc082018-10-23 12:03:01 +020029#include "rtc_base/thread_annotations.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020030
31#if defined(WEBRTC_WIN)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/win32.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020033#endif
34
35namespace rtc {
36
37class Thread;
38
Henrik Boströmba4dcc32019-02-28 09:34:06 +010039namespace rtc_thread_internal {
40
41template <class FunctorT>
42class SingleMessageHandlerWithFunctor final : public MessageHandler {
43 public:
44 explicit SingleMessageHandlerWithFunctor(FunctorT&& functor)
45 : functor_(std::forward<FunctorT>(functor)) {}
46
47 void OnMessage(Message* msg) override {
48 functor_();
49 delete this;
50 }
51
52 private:
53 ~SingleMessageHandlerWithFunctor() override {}
54
55 typename std::remove_reference<FunctorT>::type functor_;
56
57 RTC_DISALLOW_COPY_AND_ASSIGN(SingleMessageHandlerWithFunctor);
58};
59
60} // namespace rtc_thread_internal
61
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020062class ThreadManager {
63 public:
64 static const int kForever = -1;
65
66 // Singleton, constructor and destructor are private.
67 static ThreadManager* Instance();
68
69 Thread* CurrentThread();
70 void SetCurrentThread(Thread* thread);
71
72 // Returns a thread object with its thread_ ivar set
73 // to whatever the OS uses to represent the thread.
74 // If there already *is* a Thread object corresponding to this thread,
75 // this method will return that. Otherwise it creates a new Thread
76 // object whose wrapped() method will return true, and whose
77 // handle will, on Win32, be opened with only synchronization privileges -
78 // if you need more privilegs, rather than changing this method, please
79 // write additional code to adjust the privileges, or call a different
80 // factory method of your own devising, because this one gets used in
81 // unexpected contexts (like inside browser plugins) and it would be a
82 // shame to break it. It is also conceivable on Win32 that we won't even
83 // be able to get synchronization privileges, in which case the result
84 // will have a null handle.
Yves Gerey665174f2018-06-19 15:03:05 +020085 Thread* WrapCurrentThread();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020086 void UnwrapCurrentThread();
87
88 bool IsMainThread();
89
90 private:
91 ThreadManager();
92 ~ThreadManager();
93
94#if defined(WEBRTC_POSIX)
95 pthread_key_t key_;
96#endif
97
98#if defined(WEBRTC_WIN)
Tommi51492422017-12-04 15:18:23 +010099 const DWORD key_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200100#endif
101
102 // The thread to potentially autowrap.
Tommi51492422017-12-04 15:18:23 +0100103 const PlatformThreadRef main_thread_ref_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200104
105 RTC_DISALLOW_COPY_AND_ASSIGN(ThreadManager);
106};
107
108struct _SendMessage {
109 _SendMessage() {}
Yves Gerey665174f2018-06-19 15:03:05 +0200110 Thread* thread;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200111 Message msg;
Yves Gerey665174f2018-06-19 15:03:05 +0200112 bool* ready;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200113};
114
115class Runnable {
116 public:
117 virtual ~Runnable() {}
118 virtual void Run(Thread* thread) = 0;
119
120 protected:
121 Runnable() {}
122
123 private:
124 RTC_DISALLOW_COPY_AND_ASSIGN(Runnable);
125};
126
127// WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread().
128
danilchap3c6abd22017-09-06 05:46:29 -0700129class RTC_LOCKABLE Thread : public MessageQueue {
tommia8a35152017-07-13 05:47:25 -0700130 public:
Erik Språng6e70f182019-05-16 10:27:17 +0000131 // DEPRECATED.
132 // The default constructor should not be used because it hides whether or
133 // not a socket server will be associated with the thread. Most instances
134 // of Thread do actually not need one, so please use either of the Create*
135 // methods to construct an instance of Thread.
136 Thread();
137
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200138 explicit Thread(SocketServer* ss);
139 explicit Thread(std::unique_ptr<SocketServer> ss);
Taylor Brandstetter08672602018-03-02 15:20:33 -0800140 // Constructors meant for subclasses; they should call DoInit themselves and
141 // pass false for |do_init|, so that DoInit is called only on the fully
142 // instantiated class, which avoids a vptr data race.
143 Thread(SocketServer* ss, bool do_init);
144 Thread(std::unique_ptr<SocketServer> ss, bool do_init);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200145
146 // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or
147 // guarantee Stop() is explicitly called before the subclass is destroyed).
148 // This is required to avoid a data race between the destructor modifying the
149 // vtable, and the Thread::PreRun calling the virtual method Run().
150 ~Thread() override;
151
152 static std::unique_ptr<Thread> CreateWithSocketServer();
153 static std::unique_ptr<Thread> Create();
154 static Thread* Current();
155
156 // Used to catch performance regressions. Use this to disallow blocking calls
157 // (Invoke) for a given scope. If a synchronous call is made while this is in
158 // effect, an assert will be triggered.
159 // Note that this is a single threaded class.
160 class ScopedDisallowBlockingCalls {
161 public:
162 ScopedDisallowBlockingCalls();
Sebastian Jansson9debe5a2019-03-22 15:42:38 +0100163 ScopedDisallowBlockingCalls(const ScopedDisallowBlockingCalls&) = delete;
164 ScopedDisallowBlockingCalls& operator=(const ScopedDisallowBlockingCalls&) =
165 delete;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200166 ~ScopedDisallowBlockingCalls();
Yves Gerey665174f2018-06-19 15:03:05 +0200167
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200168 private:
169 Thread* const thread_;
170 const bool previous_state_;
171 };
172
173 bool IsCurrent() const;
174
175 // Sleeps the calling thread for the specified number of milliseconds, during
176 // which time no processing is performed. Returns false if sleeping was
177 // interrupted by a signal (POSIX only).
178 static bool SleepMs(int millis);
179
180 // Sets the thread's name, for debugging. Must be called before Start().
181 // If |obj| is non-null, its value is appended to |name|.
182 const std::string& name() const { return name_; }
183 bool SetName(const std::string& name, const void* obj);
184
185 // Starts the execution of the thread.
186 bool Start(Runnable* runnable = nullptr);
187
188 // Tells the thread to stop and waits until it is joined.
189 // Never call Stop on the current thread. Instead use the inherited Quit
190 // function which will exit the base MessageQueue without terminating the
191 // underlying OS thread.
192 virtual void Stop();
193
194 // By default, Thread::Run() calls ProcessMessages(kForever). To do other
195 // work, override Run(). To receive and dispatch messages, call
196 // ProcessMessages occasionally.
197 virtual void Run();
198
199 virtual void Send(const Location& posted_from,
200 MessageHandler* phandler,
201 uint32_t id = 0,
202 MessageData* pdata = nullptr);
203
204 // Convenience method to invoke a functor on another thread. Caller must
205 // provide the |ReturnT| template argument, which cannot (easily) be deduced.
206 // Uses Send() internally, which blocks the current thread until execution
207 // is complete.
208 // Ex: bool result = thread.Invoke<bool>(RTC_FROM_HERE,
209 // &MyFunctionReturningBool);
210 // NOTE: This function can only be called when synchronous calls are allowed.
211 // See ScopedDisallowBlockingCalls for details.
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100212 // NOTE: Blocking invokes are DISCOURAGED, consider if what you're doing can
213 // be achieved with PostTask() and callbacks instead.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200214 template <class ReturnT, class FunctorT>
Karl Wibergd6b48192017-10-16 23:01:06 +0200215 ReturnT Invoke(const Location& posted_from, FunctorT&& functor) {
216 FunctorMessageHandler<ReturnT, FunctorT> handler(
217 std::forward<FunctorT>(functor));
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200218 InvokeInternal(posted_from, &handler);
219 return handler.MoveResult();
220 }
221
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100222 // Posts a task to invoke the functor on |this| thread asynchronously, i.e.
223 // without blocking the thread that invoked PostTask(). Ownership of |functor|
224 // is passed and destroyed on |this| thread after it is invoked.
225 // 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 //
233 // Example - Calling a class method:
234 // class Foo {
235 // public:
236 // void DoTheThing();
237 // };
238 // Foo foo;
239 // thread->PostTask(RTC_FROM_HERE, Bind(&Foo::DoTheThing, &foo));
240 //
241 // Example - Calling a lambda function:
242 // thread->PostTask(RTC_FROM_HERE,
243 // [&x, &y] { x.TrackComputations(y.Compute()); });
244 template <class FunctorT>
245 void PostTask(const Location& posted_from, FunctorT&& functor) {
246 Post(posted_from,
247 new rtc_thread_internal::SingleMessageHandlerWithFunctor<FunctorT>(
248 std::forward<FunctorT>(functor)));
249 // This DCHECK guarantees that the post was successful.
250 // Post() doesn't say whether it succeeded, but it will only fail if the
251 // thread is quitting. DCHECKing that the thread is not quitting *after*
252 // posting might yield some false positives (where the thread did in fact
253 // quit, but only after posting), but if we have false positives here then
254 // we have a race condition anyway.
255 // TODO(https://crbug.com/webrtc/10364): When Post() returns a bool we can
256 // DCHECK the result instead of inferring success from IsQuitting().
257 RTC_DCHECK(!IsQuitting());
258 }
259
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200260 // From MessageQueue
Niels Möller8909a632018-09-06 08:42:44 +0200261 bool IsProcessingMessagesForTesting() override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200262 void Clear(MessageHandler* phandler,
263 uint32_t id = MQID_ANY,
264 MessageList* removed = nullptr) override;
265 void ReceiveSends() override;
266
267 // ProcessMessages will process I/O and dispatch messages until:
268 // 1) cms milliseconds have elapsed (returns true)
269 // 2) Stop() is called (returns false)
270 bool ProcessMessages(int cms);
271
272 // Returns true if this is a thread that we created using the standard
273 // constructor, false if it was created by a call to
274 // ThreadManager::WrapCurrentThread(). The main thread of an application
275 // is generally not owned, since the OS representation of the thread
276 // obviously exists before we can get to it.
277 // You cannot call Start on non-owned threads.
278 bool IsOwned();
279
Tommi51492422017-12-04 15:18:23 +0100280 // Expose private method IsRunning() for tests.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200281 //
282 // DANGER: this is a terrible public API. Most callers that might want to
283 // call this likely do not have enough control/knowledge of the Thread in
284 // question to guarantee that the returned value remains true for the duration
285 // of whatever code is conditionally executing because of the return value!
Tommi51492422017-12-04 15:18:23 +0100286 bool RunningForTest() { return IsRunning(); }
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200287
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200288 // These functions are public to avoid injecting test hooks. Don't call them
289 // outside of tests.
290 // This method should be called when thread is created using non standard
291 // method, like derived implementation of rtc::Thread and it can not be
292 // started by calling Start(). This will set started flag to true and
293 // owned to false. This must be called from the current thread.
294 bool WrapCurrent();
295 void UnwrapCurrent();
296
Karl Wiberg32562252019-02-21 13:38:30 +0100297 // Sets the per-thread allow-blocking-calls flag to false; this is
298 // irrevocable. Must be called on this thread.
299 void DisallowBlockingCalls() { SetAllowBlockingCalls(false); }
300
301#ifdef WEBRTC_ANDROID
302 // Sets the per-thread allow-blocking-calls flag to true, sidestepping the
303 // invariants upheld by DisallowBlockingCalls() and
304 // ScopedDisallowBlockingCalls. Must be called on this thread.
305 void DEPRECATED_AllowBlockingCalls() { SetAllowBlockingCalls(true); }
306#endif
307
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200308 protected:
309 // Same as WrapCurrent except that it never fails as it does not try to
310 // acquire the synchronization access of the thread. The caller should never
311 // call Stop() or Join() on this thread.
312 void SafeWrapCurrent();
313
314 // Blocks the calling thread until this thread has terminated.
315 void Join();
316
317 static void AssertBlockingIsAllowedOnCurrentThread();
318
319 friend class ScopedDisallowBlockingCalls;
320
321 private:
322 struct ThreadInit {
323 Thread* thread;
324 Runnable* runnable;
325 };
326
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
Yves Gerey665174f2018-06-19 15:03:05 +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_