|
// NotifierAppDoc.cpp : implementation of the CNotifierAppDoc class
//
#include "stdafx.h"
#include "NotifierApp.h"
#include "NotifyObject.h"
#include "NotifyObjects.h"
#include "NotifierAppDoc.h"
#include <deque>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define THREAD_INFORMATION_RETURN (UINT)(-101)
#define THREAD_ERROR_RETURN (UINT)(-102)
// CNotifierAppDoc
IMPLEMENT_DYNCREATE(CNotifierAppDoc, CDocument)
BEGIN_MESSAGE_MAP(CNotifierAppDoc, CDocument)
END_MESSAGE_MAP()
// CNotifierAppDoc construction/destruction
CNotifierAppDoc::CNotifierAppDoc()
{
m_IsInitialized = FALSE ;
}
CNotifierAppDoc::~CNotifierAppDoc()
{
m_InformationDeque->Push( PTS_STOP ) ;
WaitForSingleObject( m_InformationThread->m_hThread, INFINITE ) ;
m_InformationThread->Delete() ;
signal_fifo::Destroy( &m_InformationDeque ) ;
m_ErrorDeque->Push( PTS_STOP ) ;
WaitForSingleObject( m_ErrorThread->m_hThread, INFINITE ) ;
m_ErrorThread->Delete() ;
signal_fifo::Destroy( &m_ErrorDeque ) ;
}
BOOL CNotifierAppDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
if ( m_IsInitialized == FALSE )
{
signal_fifo::Create( &m_InformationDeque ) ;
m_InformationThread = ::AfxBeginThread( InformationThread, (LPVOID)this, THREAD_PRIORITY_NORMAL, CREATE_SUSPENDED, 0, NULL ) ;
m_InformationThread->m_bAutoDelete = false ;
signal_fifo::Create( &m_ErrorDeque ) ;
m_ErrorThread = ::AfxBeginThread( ErrorThread, (LPVOID)this, THREAD_PRIORITY_NORMAL, CREATE_SUSPENDED, 0, NULL ) ;
m_ErrorThread->m_bAutoDelete = false ;
m_IsInitialized = TRUE ;
}
return TRUE;
}
UINT CNotifierAppDoc::InformationThread( void * p )
{
CNotifierAppDoc * Doc = reinterpret_cast<CNotifierAppDoc*>(p) ;
ASSERT( Doc ) ;
int index = 1 ;
bool _Stop = false ;
do
{
DWORD State = WaitForSingleObject( Doc->m_InformationDeque->Event(), 1000L ) ;
if ( State == WAIT_OBJECT_0 )
{
PTSIGNAL Signal = PTS_EMPTY ;
do
{
Signal = Doc->m_InformationDeque->Pop() ;
switch ( Signal )
{
case PTS_EMPTY:
TRACE( _T("CNotifierAppDoc::InformationThread() : PTS_EMPTY\n") ) ;
// It may be that another thread got this first
break ;
case PTS_SIGNAL:
TRACE( _T("CNotifierAppDoc::InformationThread() : PTS_SIGNAL\n") ) ;
Sleep(500); // wait for .5 sec before executing
Doc->OnInformationThread( index++ ) ;
break ;
case PTS_STOP:
TRACE( _T("CNotifierAppDoc::InformationThread() : PTS_STOP\n") ) ;
Sleep(3000) ;
_Stop = true ;
break ;
}
} while ( Signal == PTS_SIGNAL ) ;
}
} while ( _Stop == false ) ;
return THREAD_INFORMATION_RETURN ;
}
UINT CNotifierAppDoc::ErrorThread( void * p )
{
CNotifierAppDoc * Doc = reinterpret_cast<CNotifierAppDoc*>(p) ;
ASSERT( Doc ) ;
int index = 1 ;
bool _Stop = false ;
do
{
DWORD State = WaitForSingleObject( Doc->m_ErrorDeque->Event(), 1000L ) ;
if ( State == WAIT_OBJECT_0 )
{
PTSIGNAL Signal = PTS_EMPTY ;
do
{
Signal = Doc->m_ErrorDeque->Pop() ;
switch ( Signal )
{
case PTS_EMPTY:
TRACE( _T("CNotifierAppDoc::ErrorThread() : PTS_EMPTY\n") ) ;
// It may be that another thread got this first
break ;
case PTS_SIGNAL:
TRACE( _T("CNotifierAppDoc::ErrorThread() : PTS_SIGNAL\n") ) ;
Sleep(2000); // wait for 2 sec before executing
Doc->OnErrorThread( index++ ) ;
break ;
case PTS_STOP:
TRACE( _T("CNotifierAppDoc::ErrorThread() : PTS_STOP\n") ) ;
Sleep(5000) ;
_Stop = true ;
break ;
}
} while ( Signal == PTS_SIGNAL ) ;
}
} while ( _Stop == false ) ;
return THREAD_ERROR_RETURN ;
}
void CNotifierAppDoc::OnErrorThread( int index )
{
TRACE( _T("CNotifierAppDoc::OnErrorThread()\n") ) ;
HWND hMain = AfxGetApp()->m_pMainWnd->GetSafeHwnd() ;
NMHDR hdr = { hMain, IDD_NotifyAppDoc, 0 } ;
CString s ;
s.Format( _T("Error Item %d"), index ) ;
CErrorObject * pObject = new CErrorObject( index, s, hdr ) ;
::PostMessage( hMain, WM_NOTIFY, 0, (LPARAM)&(pObject->m_hdrObject) ) ;
}
void CNotifierAppDoc::OnInformationThread( int index )
{
TRACE( _T("CNotifierAppDoc::OnInformationThread()\n") ) ;
HWND hMain = AfxGetApp()->m_pMainWnd->GetSafeHwnd() ;
NMHDR hdr = { hMain, IDD_NotifyAppDoc, 0 } ;
CString s ;
s.Format( _T("Information Item %d"), index ) ;
CInformationObject * pObject = new CInformationObject( index, s, hdr ) ;
::PostMessage( hMain, WM_NOTIFY, 0, (LPARAM)&(pObject->m_hdrObject) ) ;
}
void CNotifierAppDoc::RequestInformation()
{
m_InformationDeque->Push( PTS_SIGNAL ) ;
}
void CNotifierAppDoc::RequestError()
{
// m_ErrorThread.Signal() ;
m_ErrorDeque->Push( PTS_SIGNAL ) ;
}
// CNotifierAppDoc serialization
void CNotifierAppDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
// CNotifierAppDoc diagnostics
#ifdef _DEBUG
void CNotifierAppDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CNotifierAppDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
BOOL CNotifierAppDoc::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if ( HIWORD(nCode) == WM_NOTIFY )
{
WORD wCode = LOWORD(nCode) ;
AFX_NOTIFY * notify = reinterpret_cast<AFX_NOTIFY*>(pExtra) ;
if ( notify->pNMHDR->idFrom == IDD_NotifyAppDoc )
{
LPNMHDROBJECT lpnmhdr = (LPNMHDROBJECT)(notify->pNMHDR) ;
CNotifyObject * pObject = lpnmhdr->pObject ;
UpdateAllViews( NULL, pObject->get_Message(), pObject ) ;
delete pObject ;
*(notify->pResult) = 1 ;
return TRUE ;
}
int x = 0 ;
}
return CDocument::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
class critical_section_t
{
public:
critical_section_t()
{
::InitializeCriticalSection( &m_CS ) ;
}
virtual ~critical_section_t()
{
::DeleteCriticalSection( &m_CS ) ;
}
operator LPCRITICAL_SECTION()
{
return &m_CS ;
}
protected:
CRITICAL_SECTION m_CS ;
};
class cs_lock_t
{
public:
cs_lock_t( critical_section_t & cst )
{
m_pCS = (LPCRITICAL_SECTION)cst ;
::EnterCriticalSection( m_pCS ) ;
}
cs_lock_t( LPCRITICAL_SECTION pcs )
{
m_pCS = pcs ;
::EnterCriticalSection( m_pCS ) ;
}
virtual ~cs_lock_t()
{
::LeaveCriticalSection(m_pCS) ;
}
protected:
CRITICAL_SECTION * m_pCS ;
};
class signal_fifo_impl : public signal_fifo
{
protected:
typedef std::deque<PTSIGNAL> signals_t ;
typedef signals_t::iterator signals_ptr ;
public:
signal_fifo_impl()
{
m_Event = CreateEvent(NULL, FALSE, FALSE, NULL ) ;
}
~signal_fifo_impl()
{
CloseHandle( m_Event ) ;
}
virtual PTSIGNAL Pop()
{
PTSIGNAL pop = PTS_EMPTY ;
if ( m_Signals.size() > 0 )
{
cs_lock_t lock(m_CS) ;
pop = m_Signals[0] ;
m_Signals.pop_front() ;
}
return pop ;
}
virtual void Push( PTSIGNAL Signal )
{
{
cs_lock_t lock(m_CS) ;
m_Signals.push_back( Signal ) ;
}
::SetEvent( m_Event ) ;
}
virtual size_t Size()
{
size_t sReturn = 0 ;
{
cs_lock_t lock(m_CS) ;
sReturn = m_Signals.size() ;
}
return sReturn ;
}
virtual HANDLE & Event()
{
return m_Event ;
}
protected:
HANDLE m_Event ;
signals_t m_Signals ;
critical_section_t m_CS ;
};
void signal_fifo::Create( signal_fifo ** signals )
{
signal_fifo_impl * p = new signal_fifo_impl ;
*signals = p ;
}
void signal_fifo::Destroy( signal_fifo ** signals )
{
delete *signals ;
*signals = NULL ;
}
|
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.