// Timer.cpp: implementation of the Timer class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Timer.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// Timer::Timer() { m_bStop=true; m_msTimeout=-1; m_hThreadDone = NULL; m_hThreadDone = CreateEvent(NULL,FALSE, FALSE, NULL); ASSERT (m_hThreadDone); SetEvent(m_hThreadDone); // code added m_hEndThread = NULL; m_hEndThread = CreateEvent(NULL,FALSE, FALSE, NULL); ASSERT (m_hEndThread); SetEvent(m_hEndThread); } Timer::~Timer() { //dont destruct until the thread is done DWORD ret=WaitForSingleObject(m_hEndThread,INFINITE); ASSERT(ret==WAIT_OBJECT_0); Sleep(500); CloseHandle(m_hEndThread) ; } void Timer::Tick() { //Will be overriden by subclass } void Timer::StartTicking() { if (m_bStop==false) return; ///ignore, it is already ticking... m_bStop=false; ResetEvent(m_hThreadDone); ResetEvent(m_hEndThread); AfxBeginThread(TickerThread, this); } UINT Timer::TickerThread(LPVOID pParam) { Timer* me=(Timer*) pParam; ASSERT (me->m_msTimeout!=-1); while (!me->m_bStop) { // Sleep() is changed to this so that a termination of a thread will be received. if (WaitForSingleObject(me->m_hEndThread,me->GetTimeout()) == WAIT_TIMEOUT) { // No signal received.. me->Tick(); } else { // Signal received to stop the thread. me->m_bStop = true; } } SetEvent(me->m_hThreadDone); return 0; } void Timer::StopTicking() { if (m_bStop==true) return; ///ignore, it is not ticking... m_bStop=true; //ok make it stop SetEvent(m_hEndThread); WaitForSingleObject(m_hThreadDone,INFINITE); //The above ensures that we do not return UNTIL the thread //has finished. This way we dont allow the user to start multiple //threads that will execute Tick() at the same time }