blob: 738a243c03e2b65ca46afb5550374d6eded9be10 [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:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200131 explicit Thread(SocketServer* ss);
132 explicit Thread(std::unique_ptr<SocketServer> ss);
Taylor Brandstetter08672602018-03-02 15:20:33 -0800133 // Constructors meant for subclasses; they should call DoInit themselves and
134 // pass false for |do_init|, so that DoInit is called only on the fully
135 // instantiated class, which avoids a vptr data race.
136 Thread(SocketServer* ss, bool do_init);
137 Thread(std::unique_ptr<SocketServer> ss, bool do_init);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200138
139 // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or
140 // guarantee Stop() is explicitly called before the subclass is destroyed).
141 // This is required to avoid a data race between the destructor modifying the
142 // vtable, and the Thread::PreRun calling the virtual method Run().
143 ~Thread() override;
144
145 static std::unique_ptr<Thread> CreateWithSocketServer();
146 static std::unique_ptr<Thread> Create();
147 static Thread* Current();
148
149 // Used to catch performance regressions. Use this to disallow blocking calls
150 // (Invoke) for a given scope. If a synchronous call is made while this is in
151 // effect, an assert will be triggered.
152 // Note that this is a single threaded class.
153 class ScopedDisallowBlockingCalls {
154 public:
155 ScopedDisallowBlockingCalls();
Sebastian Jansson9debe5a2019-03-22 15:42:38 +0100156 ScopedDisallowBlockingCalls(const ScopedDisallowBlockingCalls&) = delete;
157 ScopedDisallowBlockingCalls& operator=(const ScopedDisallowBlockingCalls&) =
158 delete;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200159 ~ScopedDisallowBlockingCalls();
Yves Gerey665174f2018-06-19 15:03:05 +0200160
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200161 private:
162 Thread* const thread_;
163 const bool previous_state_;
164 };
165
166 bool IsCurrent() const;
167
168 // Sleeps the calling thread for the specified number of milliseconds, during
169 // which time no processing is performed. Returns false if sleeping was
170 // interrupted by a signal (POSIX only).
171 static bool SleepMs(int millis);
172
173 // Sets the thread's name, for debugging. Must be called before Start().
174 // If |obj| is non-null, its value is appended to |name|.
175 const std::string& name() const { return name_; }
176 bool SetName(const std::string& name, const void* obj);
177
178 // Starts the execution of the thread.
179 bool Start(Runnable* runnable = nullptr);
180
181 // Tells the thread to stop and waits until it is joined.
182 // Never call Stop on the current thread. Instead use the inherited Quit
183 // function which will exit the base MessageQueue without terminating the
184 // underlying OS thread.
185 virtual void Stop();
186
187 // By default, Thread::Run() calls ProcessMessages(kForever). To do other
188 // work, override Run(). To receive and dispatch messages, call
189 // ProcessMessages occasionally.
190 virtual void Run();
191
192 virtual void Send(const Location& posted_from,
193 MessageHandler* phandler,
194 uint32_t id = 0,
195 MessageData* pdata = nullptr);
196
197 // Convenience method to invoke a functor on another thread. Caller must
198 // provide the |ReturnT| template argument, which cannot (easily) be deduced.
199 // Uses Send() internally, which blocks the current thread until execution
200 // is complete.
201 // Ex: bool result = thread.Invoke<bool>(RTC_FROM_HERE,
202 // &MyFunctionReturningBool);
203 // NOTE: This function can only be called when synchronous calls are allowed.
204 // See ScopedDisallowBlockingCalls for details.
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100205 // NOTE: Blocking invokes are DISCOURAGED, consider if what you're doing can
206 // be achieved with PostTask() and callbacks instead.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200207 template <class ReturnT, class FunctorT>
Karl Wibergd6b48192017-10-16 23:01:06 +0200208 ReturnT Invoke(const Location& posted_from, FunctorT&& functor) {
209 FunctorMessageHandler<ReturnT, FunctorT> handler(
210 std::forward<FunctorT>(functor));
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200211 InvokeInternal(posted_from, &handler);
212 return handler.MoveResult();
213 }
214
Henrik Boströmba4dcc32019-02-28 09:34:06 +0100215 // Posts a task to invoke the functor on |this| thread asynchronously, i.e.
216 // without blocking the thread that invoked PostTask(). Ownership of |functor|
217 // is passed and destroyed on |this| thread after it is invoked.
218 // Requirements of FunctorT:
219 // - FunctorT is movable.
220 // - FunctorT implements "T operator()()" or "T operator()() const" for some T
221 // (if T is not void, the return value is discarded on |this| thread).
222 // - FunctorT has a public destructor that can be invoked from |this| thread
223 // after operation() has been invoked.
224 // - The functor must not cause the thread to quit before PostTask() is done.
225 //
226 // Example - Calling a class method:
227 // class Foo {
228 // public:
229 // void DoTheThing();
230 // };
231 // Foo foo;
232 // thread->PostTask(RTC_FROM_HERE, Bind(&Foo::DoTheThing, &foo));
233 //
234 // Example - Calling a lambda function:
235 // thread->PostTask(RTC_FROM_HERE,
236 // [&x, &y] { x.TrackComputations(y.Compute()); });
237 template <class FunctorT>
238 void PostTask(const Location& posted_from, FunctorT&& functor) {
239 Post(posted_from,
240 new rtc_thread_internal::SingleMessageHandlerWithFunctor<FunctorT>(
241 std::forward<FunctorT>(functor)));
242 // This DCHECK guarantees that the post was successful.
243 // Post() doesn't say whether it succeeded, but it will only fail if the
244 // thread is quitting. DCHECKing that the thread is not quitting *after*
245 // posting might yield some false positives (where the thread did in fact
246 // quit, but only after posting), but if we have false positives here then
247 // we have a race condition anyway.
248 // TODO(https://crbug.com/webrtc/10364): When Post() returns a bool we can
249 // DCHECK the result instead of inferring success from IsQuitting().
250 RTC_DCHECK(!IsQuitting());
251 }
252
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200253 // From MessageQueue
Niels Möller8909a632018-09-06 08:42:44 +0200254 bool IsProcessingMessagesForTesting() override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200255 void Clear(MessageHandler* phandler,
256 uint32_t id = MQID_ANY,
257 MessageList* removed = nullptr) override;
258 void ReceiveSends() override;
259
260 // ProcessMessages will process I/O and dispatch messages until:
261 // 1) cms milliseconds have elapsed (returns true)
262 // 2) Stop() is called (returns false)
263 bool ProcessMessages(int cms);
264
265 // Returns true if this is a thread that we created using the standard
266 // constructor, false if it was created by a call to
267 // ThreadManager::WrapCurrentThread(). The main thread of an application
268 // is generally not owned, since the OS representation of the thread
269 // obviously exists before we can get to it.
270 // You cannot call Start on non-owned threads.
271 bool IsOwned();
272
Tommi51492422017-12-04 15:18:23 +0100273 // Expose private method IsRunning() for tests.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200274 //
275 // DANGER: this is a terrible public API. Most callers that might want to
276 // call this likely do not have enough control/knowledge of the Thread in
277 // question to guarantee that the returned value remains true for the duration
278 // of whatever code is conditionally executing because of the return value!
Tommi51492422017-12-04 15:18:23 +0100279 bool RunningForTest() { return IsRunning(); }
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200280
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200281 // These functions are public to avoid injecting test hooks. Don't call them
282 // outside of tests.
283 // This method should be called when thread is created using non standard
284 // method, like derived implementation of rtc::Thread and it can not be
285 // started by calling Start(). This will set started flag to true and
286 // owned to false. This must be called from the current thread.
287 bool WrapCurrent();
288 void UnwrapCurrent();
289
Karl Wiberg32562252019-02-21 13:38:30 +0100290 // Sets the per-thread allow-blocking-calls flag to false; this is
291 // irrevocable. Must be called on this thread.
292 void DisallowBlockingCalls() { SetAllowBlockingCalls(false); }
293
294#ifdef WEBRTC_ANDROID
295 // Sets the per-thread allow-blocking-calls flag to true, sidestepping the
296 // invariants upheld by DisallowBlockingCalls() and
297 // ScopedDisallowBlockingCalls. Must be called on this thread.
298 void DEPRECATED_AllowBlockingCalls() { SetAllowBlockingCalls(true); }
299#endif
300
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200301 protected:
302 // Same as WrapCurrent except that it never fails as it does not try to
303 // acquire the synchronization access of the thread. The caller should never
304 // call Stop() or Join() on this thread.
305 void SafeWrapCurrent();
306
307 // Blocks the calling thread until this thread has terminated.
308 void Join();
309
310 static void AssertBlockingIsAllowedOnCurrentThread();
311
312 friend class ScopedDisallowBlockingCalls;
313
314 private:
315 struct ThreadInit {
316 Thread* thread;
317 Runnable* runnable;
318 };
319
Karl Wiberg32562252019-02-21 13:38:30 +0100320 // Sets the per-thread allow-blocking-calls flag and returns the previous
321 // value. Must be called on this thread.
322 bool SetAllowBlockingCalls(bool allow);
323
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200324#if defined(WEBRTC_WIN)
325 static DWORD WINAPI PreRun(LPVOID context);
326#else
Yves Gerey665174f2018-06-19 15:03:05 +0200327 static void* PreRun(void* pv);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200328#endif
329
330 // ThreadManager calls this instead WrapCurrent() because
331 // ThreadManager::Instance() cannot be used while ThreadManager is
332 // being created.
333 // The method tries to get synchronization rights of the thread on Windows if
334 // |need_synchronize_access| is true.
335 bool WrapCurrentWithThreadManager(ThreadManager* thread_manager,
336 bool need_synchronize_access);
337
Tommi51492422017-12-04 15:18:23 +0100338 // Return true if the thread is currently running.
339 bool IsRunning();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200340
341 // Processes received "Send" requests. If |source| is not null, only requests
342 // from |source| are processed, otherwise, all requests are processed.
343 void ReceiveSendsFromThread(const Thread* source);
344
345 // If |source| is not null, pops the first "Send" message from |source| in
346 // |sendlist_|, otherwise, pops the first "Send" message of |sendlist_|.
347 // The caller must lock |crit_| before calling.
348 // Returns true if there is such a message.
349 bool PopSendMessageFromThread(const Thread* source, _SendMessage* msg);
350
351 void InvokeInternal(const Location& posted_from, MessageHandler* handler);
352
353 std::list<_SendMessage> sendlist_;
354 std::string name_;
Tommi51492422017-12-04 15:18:23 +0100355
Yves Gerey665174f2018-06-19 15:03:05 +0200356// TODO(tommi): Add thread checks for proper use of control methods.
357// Ideally we should be able to just use PlatformThread.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200358
359#if defined(WEBRTC_POSIX)
Tommi6cea2b02017-12-04 18:51:16 +0100360 pthread_t thread_ = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200361#endif
362
363#if defined(WEBRTC_WIN)
Tommi6cea2b02017-12-04 18:51:16 +0100364 HANDLE thread_ = nullptr;
365 DWORD thread_id_ = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200366#endif
367
Tommi51492422017-12-04 15:18:23 +0100368 // Indicates whether or not ownership of the worker thread lies with
369 // this instance or not. (i.e. owned_ == !wrapped).
370 // Must only be modified when the worker thread is not running.
371 bool owned_ = true;
372
373 // Only touched from the worker thread itself.
374 bool blocking_calls_allowed_ = true;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200375
376 friend class ThreadManager;
377
378 RTC_DISALLOW_COPY_AND_ASSIGN(Thread);
379};
380
381// AutoThread automatically installs itself at construction
382// uninstalls at destruction, if a Thread object is
383// _not already_ associated with the current OS thread.
384
385class AutoThread : public Thread {
386 public:
387 AutoThread();
388 ~AutoThread() override;
389
390 private:
391 RTC_DISALLOW_COPY_AND_ASSIGN(AutoThread);
392};
393
394// AutoSocketServerThread automatically installs itself at
395// construction and uninstalls at destruction. If a Thread object is
396// already associated with the current OS thread, it is temporarily
397// disassociated and restored by the destructor.
398
399class AutoSocketServerThread : public Thread {
400 public:
401 explicit AutoSocketServerThread(SocketServer* ss);
402 ~AutoSocketServerThread() override;
403
404 private:
405 rtc::Thread* old_thread_;
406
407 RTC_DISALLOW_COPY_AND_ASSIGN(AutoSocketServerThread);
408};
409
410} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000411
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200412#endif // RTC_BASE_THREAD_H_