1 /**************************************************************************** 2 * 3 * Copyright (C) 2000-2001 RealNetworks, Inc. All rights reserved. 4 * 5 * This program is free software. It may be distributed under the terms 6 * in the file LICENSE, found in the top level of the source distribution. 7 * 8 */ 9 10 #ifndef _THREAD_H 11 #define _THREAD_H 12 13 #include "types.h" 14 15 #ifdef _UNIX 16 #include <pthread.h> 17 typedef pthread_t threadobj_t; 18 typedef int waittimer_t; 19 #ifndef INFTIM 20 #define INFTIM (-1) /* Linux uses -1 but doesn't define INFTIM */ 21 #endif 22 #endif 23 #ifdef _WIN32 24 typedef HANDLE threadobj_t; 25 typedef DWORD waittimer_t; 26 #define INFTIM INFINITE 27 #endif 28 29 #include "types.h" 30 #include "tlist.h" 31 #include "stream.h" 32 #include "sock.h" 33 #include "timer.h" 34 35 class CMutex 36 { 37 private: // Unimplemented 38 CMutex( const CMutex& ); 39 CMutex& operator=( const CMutex& ); 40 41 public: 42 CMutex( void ); 43 virtual ~CMutex( void ); 44 45 void Lock( void ); 46 void Unlock( void ); 47 48 private: 49 #ifdef _UNIX 50 pthread_mutex_t m_mutex; 51 #endif 52 #ifdef _WIN32 53 HANDLE m_mutex; 54 #endif 55 }; 56 57 class CSemaphore 58 { 59 private: // Unimplemented 60 CSemaphore( const CSemaphore& ); 61 CSemaphore& operator=( const CSemaphore& ); 62 63 public: 64 CSemaphore( UINT nCount ); 65 virtual ~CSemaphore( void ); 66 67 void Lock( void ); 68 void Unlock( void ); 69 70 private: 71 #ifdef _UNIX 72 pthread_mutex_t m_mutex; 73 pthread_cond_t m_cond; 74 UINT m_count; 75 #endif 76 #ifdef _WIN32 77 HANDLE m_semaphore; 78 #endif 79 }; 80 81 /* 82 * Initializing a C++ thread object must involve two steps: creating the 83 * C++ object and creating the thread. If we create the thread in the 84 * ctor, we are courting disaster because the C++ object is not fully 85 * constructed until after the ctor finishes. If you think this is all 86 * theoretical and doesn't apply in real life, consider this: 87 * 88 * - GNU g++ will not call a derived virtual function until after 89 * the ctor is done -- it will *always* call the function defined in 90 * the current class. Been there, done that, spent hours debugging. 91 * 92 * - MS Visual C++ warns about using 'this' in the ctor. Probably 93 * because more than one programmer has been bitten doing it. 94 */ 95 96 class CThread 97 { 98 #ifdef _UNIX 99 friend void* thread_start( void* ); 100 #endif 101 #ifdef _WIN32 102 friend DWORD WINAPI thread_start( LPVOID ); 103 #endif 104 105 private: // Unimplemented 106 CThread( const CThread& ); 107 CThread& operator=( const CThread& ); 108 109 public: 110 CThread( void ); 111 virtual ~CThread( void ); 112 113 void Create( void ); 114 115 // void Suspend( void ); 116 // void Resume( void ); 117 118 static CThread* This( void ); 119 120 protected: 121 virtual bool Init( void ); 122 virtual void Run( void ); 123 virtual int Exit( void ); 124 125 private: 126 threadobj_t m_thread; 127 int m_retval; 128 }; 129 130 /* 131 * CEventThread -- the scheduler 132 */ 133 134 class CEventThread : public CThread 135 { 136 public: 137 CEventThread( void ); 138 ~CEventThread( void ); 139 140 protected: 141 virtual void Run( void ); 142 virtual bool Init( void ); 143 virtual int Exit( void ); 144 145 private: 146 friend class CSocket; 147 friend class CTimer; 148 bool AddStream( CSocket* pSock ); 149 void DelStream( CSocket* pSock ); 150 void SetStreamSelect( CSocket* pSock, UINT nWhich ); 151 void AddTimer( CTimer* pTimer ); 152 void DelTimer( CTimer* pTimer ); 153 154 void Heapify( UINT32 now, UINT n ); 155 156 private: 157 UINT m_nSocks; 158 UINT m_nSockAlloc; 159 CSocket** m_ppSocks; 160 waitobj_t* m_pWaitObjs; 161 UINT m_nTimers; 162 UINT m_nTimerAlloc; 163 CTimer** m_ppTimers; 164 }; 165 166 #endif //ndef _THREAD_H 167