CInternalDispatch.cpp [plain text]
#include "CInternalDispatch.h"
#include "CLog.h"
pthread_key_t CInternalDispatch::fThreadKey = NULL;
CInternalDispatch::CInternalDispatch( void )
{
fInternalDispatchStackHeight = -1;
bzero( fInternalMsgDataList, sizeof(fInternalMsgDataList) );
}
CInternalDispatch::~CInternalDispatch()
{
for ( int idx = 0; idx < kMaxInternalDispatchRecursion; idx++ )
{
if ( idx > 0 && fInternalMsgDataList[idx] != NULL )
DbgLog( kLogError, "CInternalDispatch::~CInternalDispatch - buffer was not popped for level <%d>", idx );
DSFree( fInternalMsgDataList[idx] );
}
}
void CInternalDispatch::SwapCurrentMessageBuffer( sComData* inOldMsgData, sComData* inNewMsgData )
{
if ( fInternalDispatchStackHeight > -1 && fInternalDispatchStackHeight < kMaxInternalDispatchRecursion &&
inOldMsgData != NULL && inNewMsgData != NULL &&
fInternalMsgDataList[fInternalDispatchStackHeight] == inOldMsgData )
{
fInternalMsgDataList[fInternalDispatchStackHeight] = inNewMsgData;
}
}
sComData* CInternalDispatch::GetCurrentMessageBuffer( void )
{
if ( fInternalDispatchStackHeight > -1 && fInternalDispatchStackHeight < kMaxInternalDispatchRecursion ) {
return fInternalMsgDataList[fInternalDispatchStackHeight];
}
else if ( fInternalDispatchStackHeight == -1 ) {
PushCurrentMessageBuffer();
return fInternalMsgDataList[fInternalDispatchStackHeight];
}
return NULL;
}
void CInternalDispatch::PopCurrentMessageBuffer( void )
{
if ( fInternalDispatchStackHeight > -1 && fInternalDispatchStackHeight < kMaxInternalDispatchRecursion ) {
DSFree( fInternalMsgDataList[fInternalDispatchStackHeight] );
}
if ( fInternalDispatchStackHeight > -1 ) {
fInternalDispatchStackHeight--;
}
}
void CInternalDispatch::PushCurrentMessageBuffer( void )
{
if ( fInternalDispatchStackHeight < kMaxInternalDispatchRecursion ) {
fInternalDispatchStackHeight++;
fInternalMsgDataList[fInternalDispatchStackHeight] = (sComData *) calloc( 1, sizeof(sComData) + kMsgBlockSize );
if ( fInternalMsgDataList[fInternalDispatchStackHeight] != NULL ) {
fInternalMsgDataList[fInternalDispatchStackHeight]->fDataSize = kMsgBlockSize;
fInternalMsgDataList[fInternalDispatchStackHeight]->fDataLength = 0;
}
}
else
{
DbgLog( kLogError, "CInternalDispatch::PushCurrentMessageBuffer - internal dispatch stack overrun - aborting" );
abort();
}
}
#pragma mark Static member functions
void CInternalDispatch::CreateThreadKey( void )
{
pthread_key_create( &fThreadKey, DeleteThreadKey );
}
void CInternalDispatch::DeleteThreadKey( void *key )
{
CInternalDispatch *thread = (CInternalDispatch *) key;
DSDelete( thread );
}
void CInternalDispatch::AddCapability( void )
{
static pthread_once_t once_init = PTHREAD_ONCE_INIT;
pthread_once( &once_init, CreateThreadKey );
if ( pthread_getspecific(fThreadKey) == NULL ) {
pthread_setspecific( fThreadKey, new CInternalDispatch );
DbgLog( kLogDebug, "CInternalDispatch::AddCapability has made thread %X internally dispatchable", pthread_self() );
}
}
CInternalDispatch *CInternalDispatch::GetThreadInternalDispatch( void )
{
return (CInternalDispatch *) pthread_getspecific( fThreadKey );
}