147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef WEBRTC_BASE_THREAD_H_ 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WEBRTC_BASE_THREAD_H_ 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <algorithm> 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <list> 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string> 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <vector> 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX) 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <pthread.h> 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/constructormagic.h" 230631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org#include "webrtc/base/event.h" 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/messagequeue.h" 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32.h" 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass Thread; 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass ThreadManager { 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ThreadManager(); 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ~ThreadManager(); 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static ThreadManager* Instance(); 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread* CurrentThread(); 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void SetCurrentThread(Thread* thread); 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Returns a thread object with its thread_ ivar set 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // to whatever the OS uses to represent the thread. 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // If there already *is* a Thread object corresponding to this thread, 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // this method will return that. Otherwise it creates a new Thread 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // object whose wrapped() method will return true, and whose 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // handle will, on Win32, be opened with only synchronization privileges - 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // if you need more privilegs, rather than changing this method, please 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // write additional code to adjust the privileges, or call a different 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // factory method of your own devising, because this one gets used in 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // unexpected contexts (like inside browser plugins) and it would be a 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // shame to break it. It is also conceivable on Win32 that we won't even 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // be able to get synchronization privileges, in which case the result 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // will have a NULL handle. 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread *WrapCurrentThread(); 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void UnwrapCurrentThread(); 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX) 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pthread_key_t key_; 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD key_; 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DISALLOW_COPY_AND_ASSIGN(ThreadManager); 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct _SendMessage { 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org _SendMessage() {} 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread *thread; 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Message msg; 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool *ready; 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgenum ThreadPriority { 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PRIORITY_IDLE = -1, 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PRIORITY_NORMAL = 0, 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PRIORITY_ABOVE_NORMAL = 1, 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PRIORITY_HIGH = 2, 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass Runnable { 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ~Runnable() {} 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void Run(Thread* thread) = 0; 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protected: 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Runnable() {} 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DISALLOW_COPY_AND_ASSIGN(Runnable); 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread(). 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass Thread : public MessageQueue { 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org explicit Thread(SocketServer* ss = NULL); 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // guarantee Stop() is explicitly called before the subclass is destroyed). 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // This is required to avoid a data race between the destructor modifying the 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // vtable, and the Thread::PreRun calling the virtual method Run(). 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ~Thread(); 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static Thread* Current(); 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 111d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org // Used to catch performance regressions. Use this to disallow blocking calls 112d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org // (Invoke) for a given scope. If a synchronous call is made while this is in 113d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org // effect, an assert will be triggered. 114d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org // Note that this is a single threaded class. 115d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org class ScopedDisallowBlockingCalls { 116d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org public: 117d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org ScopedDisallowBlockingCalls(); 118d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org ~ScopedDisallowBlockingCalls(); 119d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org private: 120d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org Thread* const thread_; 121d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org const bool previous_state_; 122d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org }; 123d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool IsCurrent() const { 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return Current() == this; 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Sleeps the calling thread for the specified number of milliseconds, during 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // which time no processing is performed. Returns false if sleeping was 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // interrupted by a signal (POSIX only). 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static bool SleepMs(int millis); 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Sets the thread's name, for debugging. Must be called before Start(). 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // If |obj| is non-NULL, its value is appended to |name|. 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const std::string& name() const { return name_; } 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool SetName(const std::string& name, const void* obj); 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Sets the thread's priority. Must be called before Start(). 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ThreadPriority priority() const { return priority_; } 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool SetPriority(ThreadPriority priority); 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Starts the execution of the thread. 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool Start(Runnable* runnable = NULL); 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Tells the thread to stop and waits until it is joined. 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Never call Stop on the current thread. Instead use the inherited Quit 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // function which will exit the base MessageQueue without terminating the 14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // underlying OS thread. 14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void Stop(); 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // By default, Thread::Run() calls ProcessMessages(kForever). To do other 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // work, override Run(). To receive and dispatch messages, call 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // ProcessMessages occasionally. 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void Run(); 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void Send(MessageHandler *phandler, uint32 id = 0, 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MessageData *pdata = NULL); 15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Convenience method to invoke a functor on another thread. Caller must 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // provide the |ReturnT| template argument, which cannot (easily) be deduced. 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Uses Send() internally, which blocks the current thread until execution 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // is complete. 16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Ex: bool result = thread.Invoke<bool>(&MyFunctionReturningBool); 164d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org // NOTE: This function can only be called when synchronous calls are allowed. 165d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org // See ScopedDisallowBlockingCalls for details. 16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org template <class ReturnT, class FunctorT> 16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ReturnT Invoke(const FunctorT& functor) { 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FunctorMessageHandler<ReturnT, FunctorT> handler(functor); 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Send(&handler); 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return handler.result(); 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // From MessageQueue 17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void Clear(MessageHandler *phandler, uint32 id = MQID_ANY, 17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MessageList* removed = NULL); 17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void ReceiveSends(); 17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // ProcessMessages will process I/O and dispatch messages until: 17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // 1) cms milliseconds have elapsed (returns true) 18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // 2) Stop() is called (returns false) 18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool ProcessMessages(int cms); 18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Returns true if this is a thread that we created using the standard 18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // constructor, false if it was created by a call to 18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // ThreadManager::WrapCurrentThread(). The main thread of an application 18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // is generally not owned, since the OS representation of the thread 18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // obviously exists before we can get to it. 18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // You cannot call Start on non-owned threads. 18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool IsOwned(); 19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HANDLE GetHandle() const { 19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return thread_; 19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD GetId() const { 19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return thread_id_; 19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#elif defined(WEBRTC_POSIX) 19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pthread_t GetPThread() { 20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return thread_; 20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2040631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org // Expose private method running() for tests. 2050631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org // 2060631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org // DANGER: this is a terrible public API. Most callers that might want to 2070631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org // call this likely do not have enough control/knowledge of the Thread in 2080631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org // question to guarantee that the returned value remains true for the duration 2090631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org // of whatever code is conditionally executing because of the return value! 2100631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org bool RunningForTest() { return running(); } 2110631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org 2128fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // Sets the per-thread allow-blocking-calls flag and returns the previous 2138fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // value. 2148fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org bool SetAllowBlockingCalls(bool allow); 2158fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protected: 217692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org // This method should be called when thread is created using non standard 218692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org // method, like derived implementation of rtc::Thread and it can not be 219692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org // started by calling Start(). This will set started flag to true and 220692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org // owned to false. This must be called from the current thread. 221692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org bool WrapCurrent(); 222692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org void UnwrapCurrent(); 223692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org 224692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org // Same as WrapCurrent except that it never fails as it does not try to 225692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org // acquire the synchronization access of the thread. The caller should never 226692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org // call Stop() or Join() on this thread. 227692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org void SafeWrapCurrent(); 228692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org 22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Blocks the calling thread until this thread has terminated. 23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void Join(); 23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 232d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org static void AssertBlockingIsAllowedOnCurrentThread(); 233d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org 234d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org friend class ScopedDisallowBlockingCalls; 235d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org 23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static void *PreRun(void *pv); 23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // ThreadManager calls this instead WrapCurrent() because 24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // ThreadManager::Instance() cannot be used while ThreadManager is 24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // being created. 242692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org // The method tries to get synchronization rights of the thread on Windows if 243692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org // |need_synchronize_access| is true. 244692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org bool WrapCurrentWithThreadManager(ThreadManager* thread_manager, 245692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org bool need_synchronize_access); 24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2470631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org // Return true if the thread was started and hasn't yet stopped. 2480631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org bool running() { return running_.Wait(0); } 2490631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org 2508fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // Processes received "Send" requests. If |source| is not NULL, only requests 2518fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // from |source| are processed, otherwise, all requests are processed. 2528fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org void ReceiveSendsFromThread(const Thread* source); 2538fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 2548fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // If |source| is not NULL, pops the first "Send" message from |source| in 2558fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // |sendlist_|, otherwise, pops the first "Send" message of |sendlist_|. 2568fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // The caller must lock |crit_| before calling. 2578fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // Returns true if there is such a message. 2588fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org bool PopSendMessageFromThread(const Thread* source, _SendMessage* msg); 2598fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::list<_SendMessage> sendlist_; 26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string name_; 26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ThreadPriority priority_; 2630631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org Event running_; // Signalled means running. 26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX) 26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org pthread_t thread_; 26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HANDLE thread_; 27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DWORD thread_id_; 27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool owned_; 275d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org bool blocking_calls_allowed_; // By default set to |true|. 27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org friend class ThreadManager; 27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DISALLOW_COPY_AND_ASSIGN(Thread); 28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// AutoThread automatically installs itself at construction 28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// uninstalls at destruction, if a Thread object is 28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// _not already_ associated with the current OS thread. 28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass AutoThread : public Thread { 28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org explicit AutoThread(SocketServer* ss = 0); 28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ~AutoThread(); 29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DISALLOW_COPY_AND_ASSIGN(AutoThread); 29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Win32 extension for threads that need to use COM 29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass ComThread : public Thread { 29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ComThread() {} 30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ~ComThread() { Stop(); } 30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protected: 30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void Run(); 30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DISALLOW_COPY_AND_ASSIGN(ComThread); 30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Provides an easy way to install/uninstall a socketserver on a thread. 31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass SocketServerScope { 31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org explicit SocketServerScope(SocketServer* ss) { 31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org old_ss_ = Thread::Current()->socketserver(); 31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread::Current()->set_socketserver(ss); 31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ~SocketServerScope() { 31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread::Current()->set_socketserver(old_ss_); 31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SocketServer* old_ss_; 32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org DISALLOW_IMPLICIT_CONSTRUCTORS(SocketServerScope); 32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_BASE_THREAD_H_ 330