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