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.

159 lines
3.1 KiB

  1. #include "priv.h"
  2. #include <mluisupp.h>
  3. #include "SmallUtil.hpp"
  4. CCancellableThread::CCancellableThread()
  5. {
  6. _hCancelEvent = NULL;
  7. _hThread = NULL;
  8. _fIsFinished = FALSE;
  9. _dwThreadResult = 0;
  10. }
  11. CCancellableThread::~CCancellableThread()
  12. {
  13. if (_hCancelEvent)
  14. CloseHandle(_hCancelEvent);
  15. if (_hThread)
  16. {
  17. DWORD dwThreadStatus;
  18. if (0 != GetExitCodeThread(_hThread, &dwThreadStatus)
  19. && dwThreadStatus == STILL_ACTIVE)
  20. {
  21. ASSERT(0); // bad error case, shouldn't need to terminate thread.
  22. TerminateThread(_hThread, 0);
  23. }
  24. CloseHandle(_hThread);
  25. }
  26. }
  27. BOOL CCancellableThread::Initialize()
  28. {
  29. BOOL retVal = FALSE;
  30. _hCancelEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  31. if (!_hCancelEvent)
  32. goto doneCCancellableThreadInitialize;
  33. retVal = TRUE;
  34. doneCCancellableThreadInitialize:
  35. return retVal;
  36. }
  37. BOOL CCancellableThread::IsCancelled()
  38. {
  39. if (!_hCancelEvent)
  40. return FALSE;
  41. DWORD dwEventWaitResult;
  42. dwEventWaitResult = WaitForSingleObject(_hCancelEvent, 0);
  43. if (dwEventWaitResult == WAIT_OBJECT_0)
  44. return TRUE;
  45. else
  46. return FALSE;
  47. }
  48. BOOL CCancellableThread::IsFinished()
  49. {
  50. return _fIsFinished;
  51. }
  52. BOOL CCancellableThread::GetResult(PDWORD pdwResult)
  53. {
  54. BOOL retVal = FALSE;
  55. if (IsFinished() != TRUE)
  56. goto doneCCancellableThreadGetStatus;
  57. *pdwResult = _dwThreadResult;
  58. retVal = TRUE;
  59. doneCCancellableThreadGetStatus:
  60. return retVal;
  61. }
  62. BOOL CCancellableThread::WaitForNotRunning(DWORD dwMilliseconds, PBOOL pfFinished)
  63. {
  64. BOOL retVal = FALSE;
  65. BOOL result;
  66. if (NULL == _hThread)
  67. {
  68. result = TRUE;
  69. }
  70. else
  71. {
  72. DWORD dwWaitResult;
  73. dwWaitResult = WaitForSingleObject(_hThread, dwMilliseconds);
  74. if (dwWaitResult == WAIT_OBJECT_0)
  75. result = TRUE;
  76. else if (dwWaitResult == WAIT_TIMEOUT)
  77. result = FALSE;
  78. else
  79. {
  80. DWORD dwError = GetLastError();
  81. goto doneCCancellableThreadWaitForComplete;
  82. }
  83. }
  84. retVal = TRUE;
  85. doneCCancellableThreadWaitForComplete:
  86. if (retVal == TRUE && pfFinished != NULL)
  87. *pfFinished = result;
  88. return retVal;
  89. }
  90. BOOL CCancellableThread::Run()
  91. {
  92. BOOL retVal = FALSE;
  93. if (!_hThread)
  94. {
  95. DWORD dw;
  96. retVal = (NULL != (_hThread = CreateThread(NULL, 0, threadProc, (void *)this, 0, &dw)));
  97. }
  98. return retVal;
  99. }
  100. BOOL CCancellableThread::NotifyCancel()
  101. {
  102. if (!_hCancelEvent)
  103. return FALSE;
  104. if (0 == SetEvent(_hCancelEvent))
  105. return FALSE;
  106. return TRUE;
  107. }
  108. DWORD WINAPI CCancellableThread::threadProc(void *pParameter)
  109. {
  110. CCancellableThread *pThis = (CCancellableThread *)pParameter;
  111. if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
  112. {
  113. pThis->_dwThreadResult = pThis->run();
  114. CoUninitialize();
  115. }
  116. pThis->_fIsFinished = TRUE;
  117. return 0;
  118. }