Source code of Windows XP (NT5)
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.

143 lines
5.0 KiB

  1. /*++
  2. Copyright (C) 2001 Microsoft Corporation
  3. Module Name:
  4. THRPOOL.H
  5. Abstract:
  6. General purpose thread pool.
  7. History:
  8. raymcc 25-Feb-99 Created
  9. --*/
  10. #ifndef _THRPOOL_H_
  11. #define _THRPOOL_H_
  12. class POLARITY CThreadPool
  13. {
  14. // User-defined control parms.
  15. // ===========================
  16. DWORD m_dwMsMaxIdle; // Max idle milliseconds before letting thread terminate
  17. LONG m_lMaxThreads; // Max threads in pool, -1 = no limit.
  18. LONG m_lIdleThreadLimit; // No more than this number of idle threads
  19. // Thread status info. These may become out-of-date as soon as they
  20. // are read, but they are statistically useful.
  21. // =================================================================
  22. LONG m_lIdleThreads; // How many threads available
  23. LONG m_lTotalThreads; // How many threads created
  24. // Other stuff.
  25. // ============
  26. HANDLE m_hReleaseThread; // Signaled to release a blocked thread
  27. HANDLE m_hBeginRendezvous; // Signaled to indicate a rendezvous
  28. HANDLE m_hParmXfer; // Signaled to begin interthread transfer of parms
  29. HANDLE m_hEndRendezvous; // Signaled when parameter transfer is completed
  30. CRITICAL_SECTION m_cs_dispatch; // Protects dispatcher rendezvous
  31. CRITICAL_SECTION m_cs_pool; // Protects thread pool rendezvous
  32. bool m_bShutdown;
  33. bool m_bPendingRequest; // Used to signal that a parm transfer
  34. // is taking place via the two Xfer members
  35. // following this.
  36. // These are used for interthread parameter transfers.
  37. // ====================================================
  38. LPVOID m_pXferUserParms; // Used to copy user-supplied thread parms
  39. LPTHREAD_START_ROUTINE m_pXferUserProc; // Used to copy the user-supplied
  40. // thread entry point
  41. LPDWORD m_pXferReturnCode; // Receives user's return code
  42. LPDWORD m_pXferElapsedTime; // Receives elapsed dispatch time
  43. HANDLE m_hXferThreadCompleted; // Signaled when thread is done
  44. // Internal functions.
  45. // ===================
  46. bool CreateNewThread();
  47. static DWORD WINAPI _ThreadEntry(LPVOID pArg);
  48. void Pool();
  49. public:
  50. enum { NoError, ExceededPool, ThreadCreationFailure, ShutdownInProgress, Failed, TimedOut };
  51. CThreadPool(
  52. DWORD dwMsMaxIdleBeforeDie = 5000, // 5 sec
  53. LONG lIdleThreadLimit = 8, // No more than this number of idle threads, -1=no limit
  54. LONG lMaxThreads = -1 // No limit
  55. );
  56. ~CThreadPool();
  57. void IncrementMaxThreads() { InterlockedIncrement(&m_lMaxThreads); }
  58. void DecrementMaxThreads() { InterlockedDecrement(&m_lMaxThreads); }
  59. LONG GetCurrentMaxThreads() { return m_lMaxThreads; }
  60. bool Shutdown(DWORD dwMaxWait = 5000);
  61. // Stops dispatching and lets thread pool return to
  62. // zero. New requests via DispatchThread() will be denied
  63. // with a <Shutdown> error code.
  64. // If this returns while there still threads due to timeout,
  65. // <false> is returned.
  66. bool Restart();
  67. // Allows thread pool to start again.
  68. // All of these can become out of date before the call even returns!
  69. // They are primarily for load analysis and don't have to be exact.
  70. // =================================================================
  71. LONG GetTotalThreadCount() { return m_lTotalThreads; }
  72. LONG GetIdleThreadCount() { return m_lIdleThreads; }
  73. // Dispatches a thread to the user's entry point.
  74. // ==============================================
  75. int DispatchThread(
  76. IN DWORD dwMaxPreferredWait,
  77. IN DWORD dwMaxWaitBeforeFail,
  78. IN LPTHREAD_START_ROUTINE pEntry,
  79. IN LPVOID pArg = 0,
  80. IN DWORD *pdwReturnCode = 0,
  81. IN DWORD *pdwElapsedTime = 0,
  82. IN HANDLE hThreadCompleted = 0
  83. );
  84. /*
  85. dwMaxPreferredWait --
  86. How long to wait while attempting to reuse a thread which
  87. has just become idle. Typically, no more than 250 msec.
  88. Once this expires, if no threads are available, one will
  89. be created, if the max thread limit hasn't been reached.
  90. If it has, then dwMaxWaitBeforeFail kicks in.
  91. dwMaxWaitBeforeFail --
  92. The maximum wait time to acquire or create a thread. If
  93. a thread cannot be dispatched within this time, ExceededPool
  94. is returned.
  95. pEntry --
  96. The user's entry point.
  97. pdwReturnCode --
  98. If not NULL, receives the thread return code.
  99. pdwElapsedTime --
  100. If not NULL, receives the elapsed running time of the dispatch.
  101. hThreadCompleted
  102. If not NULL, a user event handle to be signaled when thread is done
  103. Return value --
  104. One of the enum error codes
  105. */
  106. };
  107. #endif