EventThread.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "StdAfx.h"
  2. #include "EventThread.h"
  3. #include "Misc.h"
  4. #define EXIT_EVENT -1
  5. CEventThread::CEventThread(void)
  6. {
  7. AddEvent(EXIT_EVENT);
  8. m_hEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
  9. m_waitTimeout = INFINITE;
  10. m_threadRunning = false;
  11. m_exitThread = false;
  12. m_threadWasStarted = false;
  13. }
  14. CEventThread::~CEventThread(void)
  15. {
  16. Stop();
  17. for(EventMapType::iterator it = m_eventMap.begin(); it != m_eventMap.end(); it++)
  18. {
  19. CloseHandle(it->first);
  20. }
  21. }
  22. UINT CEventThread::EventThreadFnc(void* thisptr)
  23. {
  24. CEventThread *threadClass = (CEventThread*)thisptr;
  25. threadClass->RunThread();
  26. return 0;
  27. }
  28. void CEventThread::AddEvent(int eventId)
  29. {
  30. HANDLE handle = CreateEvent(NULL, FALSE, FALSE, _T(""));
  31. m_eventMap[handle] = eventId;
  32. }
  33. void CEventThread::AddEvent(int eventId, CString name)
  34. {
  35. HANDLE handle = CreateEvent(NULL, FALSE, FALSE, name);
  36. m_eventMap[handle] = eventId;
  37. }
  38. bool CEventThread::FireEvent(int eventId)
  39. {
  40. //Log(StrF(_T("Begin FireEvent, eventId: %d"), eventId));
  41. bool ret = false;
  42. HANDLE eventHandle = NULL;
  43. for(EventMapType::iterator it = m_eventMap.begin(); it != m_eventMap.end(); it++)
  44. {
  45. if(it->second == eventId)
  46. {
  47. eventHandle = it->first;
  48. break;
  49. }
  50. }
  51. if(eventHandle != NULL)
  52. {
  53. SetEvent(eventHandle);
  54. ret = true;
  55. }
  56. //Log(StrF(_T("End FireEvent, eventId: %d"), eventId));
  57. return false;
  58. }
  59. bool CEventThread::UndoFireEvent(int eventId)
  60. {
  61. HANDLE eventHandle = NULL;
  62. for(EventMapType::iterator it = m_eventMap.begin(); it != m_eventMap.end(); it++)
  63. {
  64. if(it->second == eventId)
  65. {
  66. eventHandle = it->first;
  67. break;
  68. }
  69. }
  70. if(eventHandle != NULL)
  71. {
  72. ResetEvent(eventHandle);
  73. return true;
  74. }
  75. return false;
  76. }
  77. void CEventThread::Start(void *param)
  78. {
  79. if(m_threadRunning == false)
  80. {
  81. ResetEvent(m_hEvt);
  82. m_exitThread = false;
  83. m_param = param;
  84. m_thread = (HANDLE)_beginthreadex(NULL, 0, EventThreadFnc, this, 0, &m_threadID);
  85. // now wait until the thread is up and really running
  86. WaitForSingleObject(m_hEvt, 1000);
  87. }
  88. else
  89. {
  90. UndoFireEvent(EXIT_EVENT);
  91. }
  92. }
  93. void CEventThread::WaitForThreadToExit(int waitTime)
  94. {
  95. WaitForSingleObject(m_hEvt, waitTime);
  96. }
  97. void CEventThread::Stop(int waitTime)
  98. {
  99. Log(_T("Start of CEventThread::Stop(int waitTime) "));
  100. if(m_threadRunning)
  101. {
  102. m_exitThread = true;
  103. FireEvent(EXIT_EVENT);
  104. if(waitTime > 0)
  105. {
  106. if (WAIT_OBJECT_0 != WaitForSingleObject(m_hEvt, waitTime))
  107. {
  108. Log(_T("Start of TerminateThread CEventThread::Stop(int waitTime) "));
  109. TerminateThread(m_thread, 0);
  110. Log(_T("End of TerminateThread CEventThread::Stop(int waitTime) "));
  111. m_threadRunning = false;
  112. }
  113. }
  114. }
  115. Log(_T("End of CEventThread::Stop(int waitTime) "));
  116. };
  117. void CEventThread::RunThread()
  118. {
  119. Log(_T("Start of CEventThread::RunThread()"));
  120. m_threadRunning = true;
  121. m_threadWasStarted = true;
  122. HANDLE *pHandleArray = new HANDLE[m_eventMap.size()];
  123. int indexPos = 0;
  124. for(EventMapType::iterator it = m_eventMap.begin(); it != m_eventMap.end(); it++)
  125. {
  126. pHandleArray[indexPos] = it->first;
  127. indexPos++;
  128. }
  129. SetEvent(m_hEvt);
  130. ResetEvent(m_hEvt);
  131. while(m_exitThread == false)
  132. {
  133. DWORD event = WaitForMultipleObjects((DWORD)m_eventMap.size(), pHandleArray, FALSE, m_waitTimeout);
  134. if(event == WAIT_FAILED)
  135. {
  136. LPVOID lpMsgBuf = NULL;
  137. DWORD dwErr = GetLastError();
  138. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  139. FORMAT_MESSAGE_FROM_SYSTEM |
  140. FORMAT_MESSAGE_IGNORE_INSERTS,
  141. NULL,
  142. dwErr,
  143. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  144. (LPTSTR) &lpMsgBuf,
  145. 0,
  146. NULL);
  147. ASSERT(!lpMsgBuf);
  148. LocalFree(lpMsgBuf);
  149. }
  150. else if(event == WAIT_TIMEOUT)
  151. {
  152. OnTimeOut(m_param);
  153. }
  154. else
  155. {
  156. HANDLE firedHandle = pHandleArray[event - WAIT_OBJECT_0];
  157. int eventId = m_eventMap[firedHandle];
  158. if(eventId == EXIT_EVENT)
  159. {
  160. break;
  161. }
  162. else
  163. {
  164. Log(StrF(_T("Start of CEventThread::RunThread() - OnEvent %d"), eventId));
  165. OnEvent(eventId, m_param);
  166. Log(StrF(_T("End of CEventThread::RunThread() - OnEvent %d"), eventId));
  167. }
  168. }
  169. }
  170. SetEvent(m_hEvt);
  171. Log(_T("End of CEventThread::RunThread()"));
  172. m_threadRunning = false;
  173. }