Listing 1
#include "TraceBuffer.h"
CTraceBuffer::CTraceBuffer() :
m_nInsertPos(-1),
m_nRetrievePos(-1)
{
memset(m_buffer, 0, sizeof(m_buffer));
m_hNumFreeEntriesSemaphore =
CreateSemaphore(NULL, TRACE_BUFFER_SIZE, TRACE_BUFFER_SIZE, NULL);
m_hNumItemsToCollectSemaphore =
CreateSemaphore(NULL, 0, TRACE_BUFFER_SIZE, NULL);
}
CTraceBuffer::~CTraceBuffer()
{
CloseHandle(m_hNumFreeEntriesSemaphore);
CloseHandle(m_hNumItemsToCollectSemaphore);
}
void CTraceBuffer::Insert(TraceLevel_En nTraceLevel, LPCTSTR lpszTrace)
{
long nPrevCount = 0;
long nInsertPos = 0;
DWORD dwTimeout = (nTraceLevel == eTraceLevelAbort ? INFINITE : 0);
// wait until there is a free position in the buffer
if (WAIT_OBJECT_0 !=
WaitForSingleObject(m_hNumFreeEntriesSemaphore, dwTimeout))
return;
nInsertPos = InterlockedIncrement(&m_nInsertPos);
TraceInfo& buffEntry = m_buffer[nInsertPos%TRACE_BUFFER_SIZE];
// insert the trace into the buff
strcpy(buffEntry.szTrace, lpszTrace);
buffEntry.nLevel = nTraceLevel;
buffEntry.dwThreadId = GetCurrentThreadId();
// after inserting new item incerement num of items to collect from buffer
ReleaseSemaphore(m_hNumItemsToCollectSemaphore, 1, &nPrevCount);
}
long CTraceBuffer::Retrieve(TraceInfo& traceInfo)
{
long nPrevNumFreeEntries = 0;
long nRetrievePos = 0;
// wait until there is at least one item to collect from buffer
if (WAIT_OBJECT_0 !=
WaitForSingleObject(m_hNumItemsToCollectSemaphore, 10000))
return 0;
nRetrievePos = InterlockedIncrement(&m_nRetrievePos);
// copy the trace info from the buffer
// don't use traceInfo =
m_buffer[nRetrievePos%TRACE_BUFFER_SIZE] - its slower!
strcpy(traceInfo.szTrace,
m_buffer[nRetrievePos%TRACE_BUFFER_SIZE].szTrace);
traceInfo.nLevel = m_buffer[nRetrievePos%TRACE_BUFFER_SIZE].nLevel;
traceInfo.dwThreadId = m_buffer[nRetrievePos%TRACE_BUFFER_SIZE].dwThreadId;
// after retrieving an item incerement num of free entries in buffer
ReleaseSemaphore(m_hNumFreeEntriesSemaphore, 1, &nPrevNumFreeEntries);
// return number traces left in buffer
return (TRACE_BUFFER_SIZE - (nPrevNumFreeEntries+1));
}