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.

175 lines
3.8 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Module : Common
  4. // Description : Generic Thread Base class
  5. // Uses Win32 SEH
  6. //
  7. // File : genthread.h
  8. // Author : kulor
  9. // Date : 05/18/2000
  10. //
  11. // History :
  12. //
  13. ///////////////////////////////////////////////////////////////////////////
  14. #pragma once
  15. ///////////////////////////////////////////////////////////////////////////
  16. //
  17. // class CGenThread
  18. //
  19. // Usage : 1) Derive from this class and implement the Run method.
  20. // 2) Use the IsStopRequested appropriately.
  21. //
  22. //
  23. typedef class CGenThread {
  24. public:
  25. CGenThread (bool fStart = false) {
  26. m_hGenThread = NULL;
  27. m_dwThreadId = 0;
  28. m_hGenStopEvent = ::CreateEvent (
  29. NULL,
  30. true,
  31. false,
  32. NULL
  33. );
  34. if ( fStart ) {
  35. Start ();
  36. }
  37. }
  38. virtual ~CGenThread () {
  39. CleanupThread ();
  40. }
  41. DWORD GetThreadId ( void ) { return m_dwThreadId ; }
  42. DWORD Start ( DWORD dwCreateFlags = 0 ) {
  43. DWORD dwRet = FALSE;
  44. if ( !fOkToRun () || IsValidThread () )
  45. return FALSE;
  46. // de-signal the event
  47. ::ResetEvent ( m_hGenStopEvent );
  48. m_hGenThread = ::CreateThread (
  49. NULL,
  50. 0,
  51. GenThreadProc,
  52. reinterpret_cast <void*>(this),
  53. 0,
  54. &m_dwThreadId
  55. );
  56. dwRet = ( m_hGenThread ? 0 : GetLastError() );
  57. return dwRet;
  58. }
  59. DWORD Stop ( void ) {
  60. if ( IsValidThread () == FALSE )
  61. return FALSE;
  62. // signal the thread
  63. ::SetEvent ( m_hGenStopEvent );
  64. // now wait for it to stop
  65. DWORD dwRet = ::WaitForSingleObject ( m_hGenThread , INFINITE );
  66. CleanupThread ();
  67. return dwRet;
  68. }
  69. DWORD Pause ( void ) {
  70. if ( IsValidThread() == FALSE )
  71. return FALSE;
  72. ::SuspendThread ( m_hGenThread );
  73. return GetLastError ();
  74. }
  75. DWORD Resume ( void ) {
  76. if ( IsValidThread() == FALSE )
  77. return FALSE;
  78. ::ResumeThread ( m_hGenThread );
  79. return GetLastError ();
  80. }
  81. bool IsStopRequested ( void ) {
  82. bool fVal = false;
  83. fVal = ( ::WaitForSingleObject ( m_hGenStopEvent, 0 ) == WAIT_OBJECT_0 );
  84. return (fVal);
  85. }
  86. virtual DWORD Run ( void ) = 0 ;
  87. bool IsValidThread ( void ) {
  88. return ( m_hGenThread != NULL );
  89. }
  90. protected:
  91. void CleanupThread ( void ) {
  92. m_dwThreadId = 0;
  93. if ( m_hGenStopEvent ) {
  94. ::CloseHandle ( m_hGenStopEvent );
  95. m_hGenStopEvent = NULL;
  96. }
  97. if ( m_hGenThread ) {
  98. ::CloseHandle ( m_hGenThread );
  99. m_hGenThread = NULL;
  100. }
  101. }
  102. virtual bool fOkToRun( void ) {
  103. return ( m_hGenStopEvent != NULL );
  104. }
  105. static DWORD WINAPI GenThreadProc(
  106. LPVOID lpParameter
  107. )
  108. {
  109. CGenThread *pGenThread = reinterpret_cast<CGenThread*> (lpParameter);
  110. DWORD dwRet = 0;
  111. if ( pGenThread ) {
  112. __try {
  113. dwRet = pGenThread->Run ();
  114. }
  115. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  116. // wireup crash info
  117. }
  118. {
  119. pGenThread->CleanupThread ();
  120. }
  121. }
  122. return dwRet;
  123. }
  124. protected:
  125. HANDLE m_hGenStopEvent;
  126. HANDLE m_hGenThread;
  127. DWORD m_dwThreadId;
  128. } CGenThread, GENTHREAD, *PGENTHREAD;