Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
12 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ThreadPool.h
  6. * Content: Functions to manage a thread pool
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 03/01/1999 jtk Derived from Utils.h
  12. ***************************************************************************/
  13. #ifndef __THREAD_POOL_H__
  14. #define __THREAD_POOL_H__
  15. //**********************************************************************
  16. // Constant definitions
  17. //**********************************************************************
  18. //**********************************************************************
  19. // Macro definitions
  20. //**********************************************************************
  21. //**********************************************************************
  22. // Structure definitions
  23. //**********************************************************************
  24. //
  25. // forward class and structure references
  26. //
  27. class CSocketPort;
  28. class CThreadPool;
  29. typedef void TIMER_EVENT_CALLBACK( void *const pContext );
  30. typedef void TIMER_EVENT_COMPLETE( const HRESULT hCompletionCode, void *const pContext );
  31. typedef struct _TIMER_OPERATION_ENTRY
  32. {
  33. CBilink Linkage; // list links
  34. void *pContext; // user context passed back in timer events
  35. //
  36. // timer information
  37. //
  38. UINT_PTR uRetryCount; // number of times to retry this event
  39. BOOL fRetryForever; // Boolean for retrying forever
  40. DWORD dwRetryInterval; // time between enums (milliseconds)
  41. DWORD dwIdleTimeout; // time at which the command sits idle after all retrys are complete
  42. BOOL fIdleWaitForever; // Boolean for waiting forever in idle state
  43. DWORD dwNextRetryTime; // time at which this event will fire next (milliseconds)
  44. TIMER_EVENT_CALLBACK *pTimerCallback; // callback for when this event fires
  45. TIMER_EVENT_COMPLETE *pTimerComplete; // callback for when this event is complete
  46. CThreadPool * pThreadPool; // handle to owning thread pool
  47. PVOID pvTimerData; // cancellable handle to timer, or NULL if not scheduled
  48. UINT uiTimerUnique; // uniqueness value for timer
  49. BOOL fCancelling; // boolean denoting whether the timer is cancelling or not
  50. #ifndef DPNBUILD_ONLYONEPROCESSOR
  51. DWORD dwCPU; // CPU on which timer is scheduled
  52. #endif // ! DPNBUILD_ONLYONEPROCESSOR
  53. #undef DPF_MODNAME
  54. #define DPF_MODNAME "_TIMER_OPERATION_ENTRY::TimerOperationFromLinkage"
  55. static _TIMER_OPERATION_ENTRY *TimerOperationFromLinkage( CBilink *const pLinkage )
  56. {
  57. DNASSERT( pLinkage != NULL );
  58. DBG_CASSERT( OFFSETOF( _TIMER_OPERATION_ENTRY, Linkage ) == 0 );
  59. return reinterpret_cast<_TIMER_OPERATION_ENTRY*>( pLinkage );
  60. }
  61. } TIMER_OPERATION_ENTRY;
  62. #ifndef DPNBUILD_ONLYONETHREAD
  63. typedef void BLOCKING_JOB_CALLBACK( void *const pvContext );
  64. typedef struct _BLOCKING_JOB
  65. {
  66. CBilink Linkage; // list links
  67. void *pvContext; // user context passed back in job callback
  68. BLOCKING_JOB_CALLBACK *pfnBlockingJobCallback; // callback for when this job is processed
  69. } BLOCKING_JOB;
  70. #endif // ! DPNBUILD_ONLYONETHREAD
  71. //**********************************************************************
  72. // Variable definitions
  73. //**********************************************************************
  74. //**********************************************************************
  75. // Function prototypes
  76. //**********************************************************************
  77. typedef BOOL (CSocketPort::*PSOCKET_SERVICE_FUNCTION)( void );
  78. typedef void DIALOG_FUNCTION( void *const pDialogContext );
  79. //
  80. // functions for managing the timer data pool
  81. //
  82. BOOL TimerEntry_Alloc( void *pItem, void* pvContext );
  83. void TimerEntry_Get( void *pItem, void* pvContext );
  84. void TimerEntry_Release( void *pItem );
  85. void TimerEntry_Dealloc( void *pItem );
  86. //**********************************************************************
  87. // Class prototypes
  88. //**********************************************************************
  89. //
  90. // class for thread pool
  91. //
  92. class CThreadPool
  93. {
  94. public:
  95. static BOOL PoolAllocFunction( void* pvItem, void* pvContext );
  96. static void PoolDeallocFunction( void* pvItem );
  97. void Lock( void ) { DNEnterCriticalSection( &m_Lock ); }
  98. void Unlock( void ) { DNLeaveCriticalSection( &m_Lock ); }
  99. #undef DPF_MODNAME
  100. #define DPF_MODNAME "CThreadPool::AddRef"
  101. void AddRef( void )
  102. {
  103. DNInterlockedIncrement( const_cast<LONG*>(&m_iRefCount) );
  104. }
  105. #undef DPF_MODNAME
  106. #define DPF_MODNAME "CThreadPool::DecRef"
  107. void DecRef( void )
  108. {
  109. DNASSERT( m_iRefCount != 0 );
  110. if ( DNInterlockedDecrement( const_cast<LONG*>(&m_iRefCount) ) == 0 )
  111. {
  112. Deinitialize();
  113. g_ThreadPoolPool.Release( this );
  114. }
  115. }
  116. HRESULT Initialize( void );
  117. void Deinitialize( void );
  118. #if ((! defined(DPNBUILD_NOWINSOCK2)) && (! defined(DPNBUILD_ONLYWINSOCK2)))
  119. CReadIOData * GetNewReadIOData(READ_IO_DATA_POOL_CONTEXT * const pContext, const BOOL fNeedOverlapped );
  120. #else // DPNBUILD_NOWINSOCK2 or DPNBUILD_ONLYWINSOCK2
  121. CReadIOData * GetNewReadIOData(READ_IO_DATA_POOL_CONTEXT * const pContext);
  122. #endif // DPNBUILD_NOWINSOCK2 or DPNBUILD_ONLYWINSOCK2
  123. static void ReturnReadIOData(CReadIOData *const pReadIOData);
  124. #ifndef DPNBUILD_ONLYWINSOCK2
  125. HRESULT AddSocketPort( CSocketPort *const pSocketPort );
  126. void RemoveSocketPort( CSocketPort *const pSocketPort );
  127. BOOL CheckWinsock1IO( FD_SET *const pWinsock1Sockets );
  128. BOOL ServiceWinsock1Sockets( FD_SET *pSocketSet, PSOCKET_SERVICE_FUNCTION pServiceFunction );
  129. static void WINAPI CheckWinsock1IOCallback( void * const pvContext,
  130. void * const pvTimerData,
  131. const UINT uiTimerUnique );
  132. #endif // ! DPNBUILD_ONLYWINSOCK2
  133. #ifdef DPNBUILD_ONLYONEPROCESSOR
  134. HRESULT SubmitDelayedCommand( const PFNDPTNWORKCALLBACK pFunction,
  135. void *const pContext );
  136. #else // ! DPNBUILD_ONLYONEPROCESSOR
  137. HRESULT SubmitDelayedCommand( const DWORD dwCPU,
  138. const PFNDPTNWORKCALLBACK pFunction,
  139. void *const pContext );
  140. #endif // ! DPNBUILD_ONLYONEPROCESSOR
  141. static void WINAPI GenericTimerCallback( void * const pvContext,
  142. void * const pvTimerData,
  143. const UINT uiTimerUnique );
  144. #ifdef DPNBUILD_ONLYONEPROCESSOR
  145. HRESULT SubmitTimerJob( const BOOL fPerformImmediately,
  146. const UINT_PTR uRetryCount,
  147. const BOOL fRetryForever,
  148. const DWORD dwRetryInterval,
  149. const BOOL fIdleWaitForever,
  150. const DWORD dwIdleTimeout,
  151. TIMER_EVENT_CALLBACK *const pTimerCallbackFunction,
  152. TIMER_EVENT_COMPLETE *const pTimerCompleteFunction,
  153. void *const pContext );
  154. #else // ! DPNBUILD_ONLYONEPROCESSOR
  155. HRESULT SubmitTimerJob( const DWORD dwCPU,
  156. const BOOL fPerformImmediately,
  157. const UINT_PTR uRetryCount,
  158. const BOOL fRetryForever,
  159. const DWORD dwRetryInterval,
  160. const BOOL fIdleWaitForever,
  161. const DWORD dwIdleTimeout,
  162. TIMER_EVENT_CALLBACK *const pTimerCallbackFunction,
  163. TIMER_EVENT_COMPLETE *const pTimerCompleteFunction,
  164. void *const pContext );
  165. #endif // ! DPNBUILD_ONLYONEPROCESSOR
  166. BOOL StopTimerJob( void *const pContext, const HRESULT hCommandResult );
  167. BOOL ModifyTimerJobNextRetryTime( void *const pContext,
  168. DWORD const dwNextRetryTime );
  169. void LockTimerData( void ) { DNEnterCriticalSection( &m_TimerDataLock ); }
  170. void UnlockTimerData( void ) { DNLeaveCriticalSection( &m_TimerDataLock ); }
  171. #ifndef DPNBUILD_ONLYONETHREAD
  172. HRESULT SubmitBlockingJob( BLOCKING_JOB_CALLBACK *const pfnBlockingJobCallback,
  173. void *const pvContext );
  174. void DoBlockingJobs( void );
  175. #endif // ! DPNBUILD_ONLYONETHREAD
  176. #ifndef DPNBUILD_NOSPUI
  177. HRESULT SpawnDialogThread( DIALOG_FUNCTION *const pDialogFunction,
  178. void *const pDialogContext );
  179. static DWORD WINAPI DialogThreadProc( void *pParam );
  180. #endif // ! DPNBUILD_NOSPUI
  181. #ifndef DPNBUILD_ONLYONETHREAD
  182. LONG GetIntendedThreadCount( void ) const { return m_iIntendedThreadCount; }
  183. void SetIntendedThreadCount( const LONG iIntendedThreadCount ) { m_iIntendedThreadCount = iIntendedThreadCount; }
  184. HRESULT GetIOThreadCount( LONG *const piThreadCount );
  185. HRESULT SetIOThreadCount( const LONG iMaxThreadCount );
  186. #endif // ! DPNBUILD_ONLYONETHREAD
  187. BOOL IsThreadCountReductionAllowed( void ) const { return m_fAllowThreadCountReduction; }
  188. HRESULT PreventThreadPoolReduction( void );
  189. #if ((! defined(DPNBUILD_NOMULTICAST)) && (defined(WINNT)))
  190. BOOL EnsureMadcapLoaded( void );
  191. #endif // ! DPNBUILD_MULTICAST and WINNT
  192. #ifndef DPNBUILD_NONATHELP
  193. void EnsureNATHelpLoaded( void );
  194. #endif // ! DPNBUILD_NONATHELP
  195. IDirectPlay8ThreadPoolWork* GetDPThreadPoolWork( void ) const { return m_pDPThreadPoolWork; }
  196. #ifndef DPNBUILD_NONATHELP
  197. BOOL IsNATHelpLoaded( void ) const { return m_fNATHelpLoaded; }
  198. BOOL IsNATHelpTimerJobSubmitted( void ) const { return m_fNATHelpTimerJobSubmitted; }
  199. void SetNATHelpTimerJobSubmitted( BOOL fValue ) { m_fNATHelpTimerJobSubmitted = fValue; }
  200. void HandleNATHelpUpdate( DWORD * const pdwTimerInterval );
  201. static void PerformSubsequentNATHelpGetCaps( void * const pvContext );
  202. static void NATHelpTimerComplete( const HRESULT hResult, void * const pContext );
  203. static void NATHelpTimerFunction( void * const pContext );
  204. #endif // DPNBUILD_NONATHELP
  205. #if ((defined(WINNT)) && (! defined(DPNBUILD_NOMULTICAST)))
  206. BOOL IsMadcapLoaded( void ) const { return m_fMadcapLoaded; }
  207. #endif // WINNT and not DPNBUILD_NOMULTICAST
  208. private:
  209. BYTE m_Sig[4]; // debugging signature ('THPL')
  210. volatile LONG m_iRefCount; // reference count
  211. IDirectPlay8ThreadPoolWork * m_pDPThreadPoolWork; // pointer to DirectPlay Thread Pool Work interface
  212. BOOL m_fAllowThreadCountReduction; // boolean indicating that the thread count is locked from being reduced
  213. #ifndef DPNBUILD_ONLYONETHREAD
  214. DNCRITICAL_SECTION m_Lock; // local object lock
  215. LONG m_iIntendedThreadCount; // how many threads will be started
  216. DNCRITICAL_SECTION m_TimerDataLock; // lock protecting timer data
  217. #endif // ! DPNBUILD_ONLYONETHREAD
  218. CBilink m_TimerJobList; // list of current active timer jobs
  219. #ifndef DPNBUILD_NONATHELP
  220. BOOL m_fNATHelpLoaded; // boolean indicating whether the NAT Help interface has been loaded
  221. BOOL m_fNATHelpTimerJobSubmitted; // whether the NAT Help refresh timer has been submitted or not
  222. DWORD m_dwNATHelpUpdateThreadID; // ID of current thread updating NAT Help status, or 0 if none
  223. #endif // DPNBUILD_NONATHELP
  224. #if ((defined(WINNT)) && (! defined(DPNBUILD_NOMULTICAST)))
  225. BOOL m_fMadcapLoaded; // boolean indicating whether the MADCAP API has been loaded
  226. #endif // WINNT and not DPNBUILD_NOMULTICAST
  227. #ifndef DPNBUILD_ONLYWINSOCK2
  228. UINT_PTR m_uReservedSocketCount; // count of sockets that are 'reserved' for use
  229. FD_SET m_SocketSet; // set of all sockets in use
  230. CSocketPort * m_pSocketPorts[FD_SETSIZE]; // set of corresponding socket ports
  231. PVOID m_pvTimerDataWinsock1IO; // cancellable handle to Winsock 1 I/O poll timer
  232. UINT m_uiTimerUniqueWinsock1IO; // uniqueness value for Winsock 1 I/O poll timer
  233. BOOL m_fCancelWinsock1IO; // whether the Winsock 1 I/O poll timer should be cancelled or not
  234. #endif // ! DPNBUILD_ONLYWINSOCK2
  235. #ifndef DPNBUILD_ONLYONETHREAD
  236. DNCRITICAL_SECTION m_csBlockingJobLock; // lock protecting blocking job queue information
  237. CBilink m_blBlockingJobQueue; // queue of blocking jobs
  238. DNHANDLE m_hBlockingJobThread; // handle to blocking job thread
  239. DNHANDLE m_hBlockingJobEvent; // handle to event used to signal blocking job thread
  240. #endif // ! DPNBUILD_ONLYONETHREAD
  241. };
  242. #undef DPF_MODNAME
  243. #endif // __THREAD_POOL_H__