|
// author : Mikhail Botcharov
// email : mbotcharov@corp.untd.com
#include "..\include\common.h"
namespace mb_thread_lib
{
CTimer::CTimer():m_hTimer(NULL)
{
m_hTimer = ::CreateEvent(NULL, FALSE, FALSE, NULL);
}
CTimer::~CTimer()
{
Stop();
CloseHandle(m_hTimer);
}
#pragma warning(push)
#pragma warning(disable:4239)
void CTimer::Start(smart_ptr<CWorkItemInterface> spWorkItem, DWORD dwDueTime)
{
if(!(m_spWorkItem == SP_NULL(CWorkItemInterface)))
return;//must stop first
m_dwDueTime = dwDueTime;
m_spWorkItem = spWorkItem;
m_TimerThread.Start(smart_ptr<CTimer, sp_no_free<CTimer> >(this));
}
#pragma warning(pop)
void CTimer::Stop()
{
if(!(m_spWorkItem == SP_NULL(CWorkItemInterface)))
m_spWorkItem->AbortWorkItem();
m_TimerThread.Stop();
m_spWorkItem = SP_NULL(CWorkItemInterface);
}
void CTimer::OnDueTime()
{
if(!(m_spWorkItem == SP_NULL(CWorkItemInterface)))
m_spWorkItem->ProcessWorkItem();
}
void CTimer::_CTimerThread::Notify(NOTIFY_EVENT_TYPE evt)
{
switch(evt)
{
case BEGIN_THREAD_EVENT:
break;
case TERMINATE_THREAD_EVENT:
SetEvent(m_spTimer->m_hTimer);
break;
default:
break;
}
}
void CTimer::_CTimerThread::Thread(smart_ptr<CTimer, sp_no_free<CTimer> > sp)
{
m_spTimer = sp;
while(WAIT_TIMEOUT == WaitWithMessageLoop(m_spTimer->m_hTimer, m_spTimer->m_dwDueTime))
{
m_spTimer->OnDueTime();
}
return;
}
#pragma warning(push)
#pragma warning(disable:4127)
DWORD CTimer::_CTimerThread::WaitWithMessageLoop(HANDLE hEvent, DWORD dwTime)
{
DWORD dwRet;
MSG msg;
DWORD dwWaitTime = dwTime;
DWORD dwStartTime = ::GetTickCount();//from 0 to ffffffff ~49 days
DWORD dwEndTime = dwStartTime + dwWaitTime;
DWORD dwCurTime;
while(1)
{
dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, dwWaitTime, QS_ALLINPUT);
if(dwRet == WAIT_TIMEOUT)
return dwRet;
if(dwRet == WAIT_OBJECT_0)
return dwRet; // The event was signaled
if(dwRet == WAIT_ABANDONED_0)
return dwRet; // Something else happened
if(dwRet == WAIT_FAILED)
return dwRet;
// There is one or more window message available. Dispatch them
while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
{
if(WM_QUIT == msg.message)
return WAIT_ABANDONED_0;//application terminates
TranslateMessage(&msg);
DispatchMessage(&msg);
if(WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
return WAIT_OBJECT_0; // Event is now signaled.
}
dwCurTime = ::GetTickCount();
if(dwCurTime < dwEndTime)
dwWaitTime = dwEndTime - dwCurTime;
else
dwWaitTime = dwCurTime - dwEndTime;//this could happened once every 49 days
}
return WAIT_FAILED;//never goes here
}
#pragma warning(pop)
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.