| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 | 
							- #include "StdAfx.h"
 
- #include "EventThread.h"
 
- #include "Misc.h"
 
- #define EXIT_EVENT -1
 
- CEventThread::CEventThread(void)
 
- {
 
- 	AddEvent(EXIT_EVENT);
 
- 	m_hEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
 
- 	m_waitTimeout = INFINITE;
 
- 	m_threadRunning = false;
 
- 	m_exitThread = false;
 
- 	m_threadWasStarted = false;
 
- }
 
- CEventThread::~CEventThread(void)
 
- {
 
- 	Stop();
 
- 	for(EventMapType::iterator it = m_eventMap.begin(); it != m_eventMap.end(); it++)
 
- 	{
 
- 		CloseHandle(it->first);
 
- 	}
 
- }
 
- UINT CEventThread::EventThreadFnc(void* thisptr) 
 
- {
 
- 	CEventThread *threadClass = (CEventThread*)thisptr;
 
- 	threadClass->RunThread();
 
- 	return 0;
 
- }
 
- void CEventThread::AddEvent(int eventId)
 
- {
 
- 	HANDLE handle = CreateEvent(NULL, FALSE, FALSE, _T(""));
 
- 	m_eventMap[handle] = eventId;
 
- }
 
- void CEventThread::AddEvent(int eventId, CString name)
 
- {
 
- 	//handle creating events cross users/cross process
 
- 	//https://stackoverflow.com/questions/29976596/shared-global-event-between-a-service-user-mode-processes-doesnt-work
 
- 	SECURITY_DESCRIPTOR sd;
 
- 	InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
 
- 	SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
 
- 	SECURITY_ATTRIBUTES sa = { 0 };
 
- 	sa.nLength = sizeof(sa);
 
- 	sa.bInheritHandle = FALSE;
 
- 	sa.lpSecurityDescriptor = &sd;
 
- 	HANDLE handle = CreateEvent(&sa, FALSE, FALSE, name);
 
- 	m_eventMap[handle] = eventId;
 
- }
 
- bool CEventThread::FireEvent(int eventId)
 
- {
 
- 	//Log(StrF(_T("Begin FireEvent, eventId: %d"), eventId));
 
- 	bool ret = false;
 
- 	HANDLE eventHandle = NULL;
 
- 	for(EventMapType::iterator it = m_eventMap.begin(); it != m_eventMap.end(); it++)
 
- 	{
 
- 		if(it->second == eventId)
 
- 		{
 
- 			eventHandle = it->first;
 
- 			break;
 
- 		}
 
- 	}
 
- 	if(eventHandle != NULL)
 
- 	{
 
- 		SetEvent(eventHandle);
 
- 		ret = true;
 
- 	}
 
- 	
 
- 	//Log(StrF(_T("End FireEvent, eventId: %d"), eventId));
 
- 	return false;
 
- }
 
- bool CEventThread::UndoFireEvent(int eventId)
 
- {
 
- 	HANDLE eventHandle = NULL;
 
- 	for(EventMapType::iterator it = m_eventMap.begin(); it != m_eventMap.end(); it++)
 
- 	{
 
- 		if(it->second == eventId)
 
- 		{
 
- 			eventHandle = it->first;
 
- 			break;
 
- 		}
 
- 	}
 
- 	if(eventHandle != NULL)
 
- 	{
 
- 		ResetEvent(eventHandle);
 
- 		return true;
 
- 	}
 
- 	return false;
 
- }
 
- void CEventThread::Start(void *param) 
 
- {
 
- 	if(m_threadRunning == false)
 
- 	{
 
- 		ResetEvent(m_hEvt);
 
- 		m_exitThread = false;
 
- 		m_param = param;
 
- 		m_thread = (HANDLE)_beginthreadex(NULL, 0, EventThreadFnc, this, 0, &m_threadID);
 
- 		// now wait until the thread is up and really running
 
- 		WaitForSingleObject(m_hEvt, 1000);
 
- 	}
 
- 	else
 
- 	{
 
- 		UndoFireEvent(EXIT_EVENT);
 
- 	}
 
- }
 
- void CEventThread::WaitForThreadToExit(int waitTime)
 
- {
 
- 	WaitForSingleObject(m_hEvt, waitTime);
 
- }
 
- void CEventThread::Stop(int waitTime) 
 
- {
 
- 	Log(StrF(_T("Start of CEventThread::Stop(int waitTime) %d - Name: %s"), waitTime, m_threadName));
 
- 	if(m_threadRunning)
 
- 	{
 
- 		m_exitThread = true;	
 
- 		FireEvent(EXIT_EVENT);
 
- 		if(waitTime > 0)
 
- 		{
 
- 			if (WAIT_OBJECT_0 != WaitForSingleObject(m_hEvt, waitTime))
 
- 			{
 
- 				Log(_T("Start of TerminateThread CEventThread::Stop(int waitTime) "));
 
- 				TerminateThread(m_thread, 0);
 
- 				Log(_T("End of TerminateThread CEventThread::Stop(int waitTime) "));
 
- 				m_threadRunning = false;
 
- 			}
 
- 		}
 
- 	}
 
- 	Log(StrF(_T("End of CEventThread::Stop(int waitTime) %d - Name: %s"), waitTime, m_threadName));
 
- };
 
- void CEventThread::RunThread()
 
- {
 
- 	Log(StrF(_T("Start of CEventThread::RunThread() Name: %s"), m_threadName));
 
- 	m_threadRunning = true;
 
- 	m_threadWasStarted = true;
 
- 	HANDLE *pHandleArray = new HANDLE[m_eventMap.size()];
 
- 	int indexPos = 0;
 
- 	for(EventMapType::iterator it = m_eventMap.begin(); it != m_eventMap.end(); it++)
 
- 	{
 
- 		if (it->first != 0)
 
- 		{
 
- 			pHandleArray[indexPos] = it->first;
 
- 			indexPos++;
 
- 		}
 
- 	}
 
- 	SetEvent(m_hEvt);
 
- 	ResetEvent(m_hEvt);
 
- 	while(m_exitThread == false)
 
- 	{
 
- 		DWORD event = WaitForMultipleObjects((DWORD)m_eventMap.size(), pHandleArray, FALSE, m_waitTimeout);
 
- 		if(event == WAIT_FAILED)
 
- 		{
 
- 			LPVOID lpMsgBuf = NULL;
 
- 			DWORD dwErr = GetLastError();
 
- 			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
 
- 							FORMAT_MESSAGE_FROM_SYSTEM |
 
- 							FORMAT_MESSAGE_IGNORE_INSERTS,
 
- 							NULL,
 
- 							dwErr,
 
- 							MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
 
- 							(LPTSTR) &lpMsgBuf,
 
- 							0,
 
- 							NULL);
 
- 			ASSERT(!lpMsgBuf);
 
- 			LocalFree(lpMsgBuf);
 
- 			Sleep(1000);
 
- 		}
 
- 		else if(event == WAIT_TIMEOUT)
 
- 		{
 
- 			OnTimeOut(m_param);
 
- 		}
 
- 		else
 
- 		{
 
- 			HANDLE firedHandle = pHandleArray[event - WAIT_OBJECT_0];
 
- 			int eventId = m_eventMap[firedHandle];
 
- 			if(eventId == EXIT_EVENT)
 
- 			{				
 
- 				break;
 
- 			}
 
- 			else
 
- 			{
 
- 				Log(StrF(_T("Start of CEventThread::RunThread() - OnEvent %d - Name %s"), eventId, m_threadName));
 
- 				OnEvent(eventId, m_param);
 
- 				Log(StrF(_T("End of CEventThread::RunThread() - OnEvent %d - Name: %d"), eventId, m_threadName));
 
- 			}
 
- 		}
 
- 	}
 
- 	UndoFireEvent(EXIT_EVENT);
 
- 	SetEvent(m_hEvt);
 
- 	Log(StrF(_T("End of CEventThread::RunThread() Name: %s"), m_threadName));
 
- 	m_threadRunning = false;
 
- }
 
 
  |