blob: 7bb7a3c130a30434272b208719ef9602bff5d00d [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:
tommie7251592017-07-14 14:44:46 -0700131 // 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.
charujaina117b042017-07-13 07:06:39 -0700136 Thread();
tommie7251592017-07-14 14:44:46 -0700137
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();
163 ~ScopedDisallowBlockingCalls();
Yves Gerey665174f2018-06-19 15:03:05 +0200164
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200165 private:
166 Thread* const thread_;
167 const bool previous_state_;
168 };
169
170 bool IsCurrent() const;
171
172 // Sleeps the calling thread for the specified number of milliseconds, during
173 // which time no processing is performed. Returns false if sleeping was
174 // interrupted by a signal (POSIX only).
175 static bool SleepMs(int millis);
176
177 // Sets the thread's name, for debugging. Must be called before Start().
178 // If |obj| is non-null, its value is appended to |name|.
179 const std::string& name() const { return name_; }
180 bool SetName(const std::string& name, const void* obj);
181
182 // Starts the execution of the thread.
183 bool Start(Runnable* runnable = nullptr);
184
185 // Tells the thread to stop and waits until it is joined.
186 // Never call Stop on the current thread. Instead use the inherited Quit
187 // function which will exit the base MessageQueue without terminating the
188 // underlying OS thread.
189 virtual void Stop();
190
191 // By default, Thread::Run() calls ProcessMessages(kForever). To do other
192 // work, override Run(). To receive and dispatch messages, call
193 // ProcessMessages occasionally.
194 virtual void Run();
195
196 virtual void Send(const Location& posted_from,
197 MessageHandler* phandler,
198 uint32_t id = 0,
199 MessageData* pdata = nullptr);
200
201 // Convenience method to invoke a functor on another thread. Caller must
202 // provide the |ReturnT| template argument, which cannot (easily) be deduced.
203 // Uses Send() internally, which blocks the current thread until execution
204 // is complete.
205 // Ex: bool result = thread.Invoke<bool>(RTC_FROM_HERE,
206 // &MyFunctionReturningBool);
207 // NOTE: This function can only be called when synchronous calls are allowed.
208 // See ScopedDisallowBlockingCalls for details.
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100209 // NOTE: Blocking invokes are DISCOURAGED, consider if what you're doing can
210 // be achieved with PostTask() and callbacks instead.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200211 template <class ReturnT, class FunctorT>
Karl Wibergd6b48192017-10-16 23:01:06 +0200212 ReturnT Invoke(const Location& posted_from, FunctorT&& functor) {
213 FunctorMessageHandler<ReturnT, FunctorT> handler(
214 std::forward<FunctorT>(functor));
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200215 InvokeInternal(posted_from, &handler);
216 return handler.MoveResult();
217 }
218
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100219 // Posts a task to invoke the functor on |this| thread asynchronously, i.e.
220 // without blocking the thread that invoked PostTask(). Ownership of |functor|
221 // is passed and destroyed on |this| thread after it is invoked.
222 // Requirements of FunctorT:
223 // - FunctorT is movable.
224 // - FunctorT implements "T operator()()" or "T operator()() const" for some T
225 // (if T is not void, the return value is discarded on |this| thread).
226 // - FunctorT has a public destructor that can be invoked from |this| thread
227 // after operation() has been invoked.
228 // - The functor must not cause the thread to quit before PostTask() is done.
229 //
230 // Example - Calling a class method:
231 // class Foo {
232 // public:
233 // void DoTheThing();
234 // };
235 // Foo foo;
236 // thread->PostTask(RTC_FROM_HERE, Bind(&Foo::DoTheThing, &foo));
237 //
238 // Example - Calling a lambda function:
239 // thread->PostTask(RTC_FROM_HERE,
240 // [&x, &y] { x.TrackComputations(y.Compute()); });
241 template <class FunctorT>
242 void PostTask(const Location& posted_from, FunctorT&& functor) {
243 Post(posted_from,
244 new rtc_thread_internal::SingleMessageHandlerWithFunctor<FunctorT>(
245 std::forward<FunctorT>(functor)));
246 // This DCHECK guarantees that the post was successful.
247 // Post() doesn't say whether it succeeded, but it will only fail if the
248 // thread is quitting. DCHECKing that the thread is not quitting *after*
249 // posting might yield some false positives (where the thread did in fact
250 // quit, but only after posting), but if we have false positives here then
251 // we have a race condition anyway.
252 // TODO(https://crbug.com/webrtc/10364): When Post() returns a bool we can
253 // DCHECK the result instead of inferring success from IsQuitting().
254 RTC_DCHECK(!IsQuitting());
255 }
256
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200257 // From MessageQueue
Niels Möller8909a632018-09-06 08:42:44 +0200258 bool IsProcessingMessagesForTesting() override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200259 void Clear(MessageHandler* phandler,
260 uint32_t id = MQID_ANY,
261 MessageList* removed = nullptr) override;
262 void ReceiveSends() override;
263
264 // ProcessMessages will process I/O and dispatch messages until:
265 // 1) cms milliseconds have elapsed (returns true)
266 // 2) Stop() is called (returns false)
267 bool ProcessMessages(int cms);
268
269 // Returns true if this is a thread that we created using the standard
270 // constructor, false if it was created by a call to
271 // ThreadManager::WrapCurrentThread(). The main thread of an application
272 // is generally not owned, since the OS representation of the thread
273 // obviously exists before we can get to it.
274 // You cannot call Start on non-owned threads.
275 bool IsOwned();
276
Tommi51492422017-12-04 15:18:23 +0100277 // Expose private method IsRunning() for tests.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200278 //
279 // DANGER: this is a terrible public API. Most callers that might want to
280 // call this likely do not have enough control/knowledge of the Thread in
281 // question to guarantee that the returned value remains true for the duration
282 // of whatever code is conditionally executing because of the return value!
Tommi51492422017-12-04 15:18:23 +0100283 bool RunningForTest() { return IsRunning(); }
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200284
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200285 // These functions are public to avoid injecting test hooks. Don't call them
286 // outside of tests.
287 // This method should be called when thread is created using non standard
288 // method, like derived implementation of rtc::Thread and it can not be
289 // started by calling Start(). This will set started flag to true and
290 // owned to false. This must be called from the current thread.
291 bool WrapCurrent();
292 void UnwrapCurrent();
293
Karl Wiberg32562252019-02-21 13:38:30 +0100294 // Sets the per-thread allow-blocking-calls flag to false; this is
295 // irrevocable. Must be called on this thread.
296 void DisallowBlockingCalls() { SetAllowBlockingCalls(false); }
297
298#ifdef WEBRTC_ANDROID
299 // Sets the per-thread allow-blocking-calls flag to true, sidestepping the
300 // invariants upheld by DisallowBlockingCalls() and
301 // ScopedDisallowBlockingCalls. Must be called on this thread.
302 void DEPRECATED_AllowBlockingCalls() { SetAllowBlockingCalls(true); }
303#endif
304
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200305 protected:
306 // Same as WrapCurrent except that it never fails as it does not try to
307 // acquire the synchronization access of the thread. The caller should never
308 // call Stop() or Join() on this thread.
309 void SafeWrapCurrent();
310
311 // Blocks the calling thread until this thread has terminated.
312 void Join();
313
314 static void AssertBlockingIsAllowedOnCurrentThread();
315
316 friend class ScopedDisallowBlockingCalls;
317
318 private:
319 struct ThreadInit {
320 Thread* thread;
321 Runnable* runnable;
322 };
323
Karl Wiberg32562252019-02-21 13:38:30 +0100324 // Sets the per-thread allow-blocking-calls flag and returns the previous
325 // value. Must be called on this thread.
326 bool SetAllowBlockingCalls(bool allow);
327
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200328#if defined(WEBRTC_WIN)
329 static DWORD WINAPI PreRun(LPVOID context);
330#else
Yves Gerey665174f2018-06-19 15:03:05 +0200331 static void* PreRun(void* pv);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200332#endif
333
334 // ThreadManager calls this instead WrapCurrent() because
335 // ThreadManager::Instance() cannot be used while ThreadManager is
336 // being created.
337 // The method tries to get synchronization rights of the thread on Windows if
338 // |need_synchronize_access| is true.
339 bool WrapCurrentWithThreadManager(ThreadManager* thread_manager,
340 bool need_synchronize_access);
341
Tommi51492422017-12-04 15:18:23 +0100342 // Return true if the thread is currently running.
343 bool IsRunning();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200344
345 // Processes received "Send" requests. If |source| is not null, only requests
346 // from |source| are processed, otherwise, all requests are processed.
347 void ReceiveSendsFromThread(const Thread* source);
348
349 // If |source| is not null, pops the first "Send" message from |source| in
350 // |sendlist_|, otherwise, pops the first "Send" message of |sendlist_|.
351 // The caller must lock |crit_| before calling.
352 // Returns true if there is such a message.
353 bool PopSendMessageFromThread(const Thread* source, _SendMessage* msg);
354
355 void InvokeInternal(const Location& posted_from, MessageHandler* handler);
356
357 std::list<_SendMessage> sendlist_;
358 std::string name_;
Tommi51492422017-12-04 15:18:23 +0100359
Yves Gerey665174f2018-06-19 15:03:05 +0200360// TODO(tommi): Add thread checks for proper use of control methods.
361// Ideally we should be able to just use PlatformThread.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200362
363#if defined(WEBRTC_POSIX)
Tommi6cea2b02017-12-04 18:51:16 +0100364 pthread_t thread_ = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200365#endif
366
367#if defined(WEBRTC_WIN)
Tommi6cea2b02017-12-04 18:51:16 +0100368 HANDLE thread_ = nullptr;
369 DWORD thread_id_ = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200370#endif
371
Tommi51492422017-12-04 15:18:23 +0100372 // Indicates whether or not ownership of the worker thread lies with
373 // this instance or not. (i.e. owned_ == !wrapped).
374 // Must only be modified when the worker thread is not running.
375 bool owned_ = true;
376
377 // Only touched from the worker thread itself.
378 bool blocking_calls_allowed_ = true;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200379
380 friend class ThreadManager;
381
382 RTC_DISALLOW_COPY_AND_ASSIGN(Thread);
383};
384
385// AutoThread automatically installs itself at construction
386// uninstalls at destruction, if a Thread object is
387// _not already_ associated with the current OS thread.
388
389class AutoThread : public Thread {
390 public:
391 AutoThread();
392 ~AutoThread() override;
393
394 private:
395 RTC_DISALLOW_COPY_AND_ASSIGN(AutoThread);
396};
397
398// AutoSocketServerThread automatically installs itself at
399// construction and uninstalls at destruction. If a Thread object is
400// already associated with the current OS thread, it is temporarily
401// disassociated and restored by the destructor.
402
403class AutoSocketServerThread : public Thread {
404 public:
405 explicit AutoSocketServerThread(SocketServer* ss);
406 ~AutoSocketServerThread() override;
407
408 private:
409 rtc::Thread* old_thread_;
410
411 RTC_DISALLOW_COPY_AND_ASSIGN(AutoSocketServerThread);
412};
413
414} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000415
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200416#endif // RTC_BASE_THREAD_H_