1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/*
2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle
3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2005, Google Inc.
4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without
6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met:
7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  1. Redistributions of source code must retain the above copyright notice,
9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer.
10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  2. Redistributions in binary form must reproduce the above copyright notice,
11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer in the documentation
12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     and/or other materials provided with the distribution.
13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  3. The name of the author may not be used to endorse or promote products
14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     derived from this software without specific prior written permission.
15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */
27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifndef TALK_BASE_THREAD_H_
29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define TALK_BASE_THREAD_H_
30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <algorithm>
32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <list>
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <string>
34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <vector>
35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef POSIX
37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <pthread.h>
38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/messagequeue.h"
41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32
43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/win32.h"
44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace talk_base {
47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass Thread;
49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass ThreadManager {
51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochpublic:
52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ThreadManager();
53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ~ThreadManager();
54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static Thread *CurrentThread();
56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static void SetCurrent(Thread *thread);
57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void Add(Thread *thread);
58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void Remove(Thread *thread);
59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Returns a thread object with its thread_ ivar set
61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // to whatever the OS uses to represent the thread.
62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // If there already *is* a Thread object corresponding to this thread,
63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // this method will return that.  Otherwise it creates a new Thread
64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // object whose wrapped() method will return true, and whose
65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // handle will, on Win32, be opened with only synchronization privileges -
66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // if you need more privilegs, rather than changing this method, please
67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // write additional code to adjust the privileges, or call a different
68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // factory method of your own devising, because this one gets used in
69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // unexpected contexts (like inside browser plugins) and it would be a
70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // shame to break it.  It is also conceivable on Win32 that we won't even
71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // be able to get synchronization privileges, in which case the result
72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // will have a NULL handle.
73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static Thread *WrapCurrentThread();
74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static void UnwrapCurrentThread();
75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static void StopAllThreads_();  // Experimental
77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochprivate:
79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Thread *main_thread_;
80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::vector<Thread *> threads_;
81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  CriticalSection crit_;
82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef POSIX
84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static pthread_key_t key_;
85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32
88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static DWORD key_;
89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass Thread;
93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct _SendMessage {
95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  _SendMessage() {}
96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Thread *thread;
97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Message msg;
98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool *ready;
99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochenum ThreadPriority {
102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  PRIORITY_HIGH,
103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  PRIORITY_ABOVE_NORMAL,
104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  PRIORITY_NORMAL,
105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  PRIORITY_IDLE,
106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass Runnable {
109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual ~Runnable() {}
111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Run(Thread* thread) = 0;
112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass Thread : public MessageQueue {
115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochpublic:
116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Thread(SocketServer* ss = NULL);
117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual ~Thread();
118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static inline Thread* Current() {
120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return ThreadManager::CurrentThread();
121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool IsCurrent() const {
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return (ThreadManager::CurrentThread() == this);
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Sleeps the calling thread for the specified number of milliseconds, during
128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // which time no processing is performed. Returns false if sleeping was
129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // interrupted by a signal (POSIX only).
130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static bool SleepMs(int millis);
131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Sets the thread's name, for debugging. Must be called before Start().
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If |obj| is non-NULL, its value is appended to |name|.
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const std::string& name() const { return name_; }
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool SetName(const std::string& name, const void* obj);
136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Sets the thread's priority. Must be called before Start().
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ThreadPriority priority() const { return priority_; }
1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool SetPriority(ThreadPriority priority);
140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Starts the execution of the thread.
142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool started() const { return started_; }
143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool Start(Runnable* runnable = NULL);
144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Tells the thread to stop and waits until it is joined.
146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Never call Stop on the current thread.  Instead use the inherited Quit
147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // function which will exit the base MessageQueue without terminating the
148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // underlying OS thread.
149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Stop();
150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // By default, Thread::Run() calls ProcessMessages(kForever).  To do other
152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // work, override Run().  To receive and dispatch messages, call
153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // ProcessMessages occasionally.
154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Run();
155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Send(MessageHandler *phandler, uint32 id = 0,
157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      MessageData *pdata = NULL);
158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // From MessageQueue
160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void Clear(MessageHandler *phandler, uint32 id = MQID_ANY,
161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                     MessageList* removed = NULL);
162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual void ReceiveSends();
163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // ProcessMessages will process I/O and dispatch messages until:
165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //  1) cms milliseconds have elapsed (returns true)
166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //  2) Stop() is called (returns false)
167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool ProcessMessages(int cms);
168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Returns true if this is a thread that we created using the standard
170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // constructor, false if it was created by a call to
171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // ThreadManager::WrapCurrentThread().  The main thread of an application
172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // is generally not owned, since the OS representation of the thread
173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // obviously exists before we can get to it.
174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // You cannot call Start on non-owned threads.
175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool IsOwned();
176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32
178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  HANDLE GetHandle() {
179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return thread_;
180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#elif POSIX
182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pthread_t GetPThread() {
183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return thread_;
184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochprivate:
188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static void *PreRun(void *pv);
189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Blocks the calling thread until this thread has terminated.
190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void Join();
191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::list<_SendMessage> sendlist_;
1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string name_;
194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ThreadPriority priority_;
195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool started_;
196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool has_sends_;
197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef POSIX
199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pthread_t thread_;
200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32
203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  HANDLE thread_;
204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool owned_;
207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  friend class ThreadManager;
209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// AutoThread automatically installs itself at construction
212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// uninstalls at destruction, if a Thread object is
213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// _not already_ associated with the current OS thread.
214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass AutoThread : public Thread {
216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochpublic:
217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  AutoThread(SocketServer* ss = 0);
218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  virtual ~AutoThread();
219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Win32 extension for threads that need to use COM
2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#ifdef WIN32
2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ComThread : public Thread {
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick protected:
2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void Run();
2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Provides an easy way to install/uninstall a socketserver on a thread.
230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass SocketServerScope {
231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit SocketServerScope(SocketServer* ss) {
233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    old_ss_ = Thread::Current()->socketserver();
234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    Thread::Current()->set_socketserver(ss);
235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ~SocketServerScope() {
237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    Thread::Current()->set_socketserver(old_ss_);
238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  SocketServer* old_ss_;
241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}  // namespace talk_base
244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // TALK_BASE_THREAD_H_
246