static TA_RetCode TA_TraceGlobalShutdown( void *globalAllocated ) { TA_TraceGlobal *global; TA_RetCode retCode = TA_SUCCESS; global = (TA_TraceGlobal *)globalAllocated; if( !global ) return retCode; if( global->fatalError.str ) TA_Free( global->fatalError.str ); #if !defined( TA_SINGLE_THREAD ) retCode = TA_SemaDestroy( &global->fatalSema ); retCode = TA_SemaDestroy( &global->callSema ); #endif #ifdef TA_DEBUG #if defined( TA_SINGLE_THREAD ) if( global->callStack ) TA_ListFree( global->callStack ); #endif if( global->functionCalled ) TA_DictFree( global->functionCalled ); #endif TA_Free( global ); return retCode; }
static TA_RetCode freeListAndElement( TA_Libc *libHandle, TA_List *list, TA_RetCode (*freeFunc)( TA_Libc *libHandle, void *toBeFreed ) ) { TA_PROLOG; TA_RetCode retCode; void *node; TA_TRACE_BEGIN( libHandle, freeListAndElement ); if( list != NULL ) { while( (node = TA_ListRemoveTail( list )) != NULL ) { retCode = freeFunc( libHandle, node ); if( retCode != TA_SUCCESS ) { TA_FATAL( libHandle, NULL, node, retCode ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } } retCode = TA_ListFree( list ); if( retCode != TA_SUCCESS ) { TA_FATAL( libHandle, NULL, list, retCode ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } } TA_TRACE_RETURN( TA_SUCCESS ); }
/**** Local functions definitions. ****/ static void stringListFree( TA_StringCache *stringCache, TA_List *list ) { TA_String *node; if( list == NULL ) return; while( (node = (TA_String *)TA_ListRemoveHead( list )) != NULL ) { TA_StringFree( stringCache, node ); } TA_ListFree( list ); }
TA_RetCode TA_PMFree( TA_PM *toBeFreed ) { TA_PMPriv *pmPriv; TA_TradeLogPriv *tradeLogPriv; if( toBeFreed ) { /* Make sure this is a valid object */ pmPriv = (TA_PMPriv *)toBeFreed->hiddenData; if( !pmPriv || (pmPriv->magicNb != TA_PMPRIV_MAGIC_NB) ) return TA_BAD_OBJECT; /* Clearly mark this object as being unusable. */ pmPriv->magicNb = 0; /* Indicate to all TA_TradeLog that they do * no belong to this TA_PM anymore. */ tradeLogPriv = TA_ListAccessHead( &pmPriv->tradeLogList ); while( tradeLogPriv ) { tradeLogPriv->nbReferenceFromTA_PM--; tradeLogPriv = TA_ListAccessNext( &pmPriv->tradeLogList ); } TA_ListFree( &pmPriv->tradeLogList ); /* Free all the cached arrays. */ FREE_IF_NOT_NULL( pmPriv->equity ); FREE_IF_NOT_NULL( pmPriv->arrayTimestamp ); FREE_IF_NOT_NULL( pmPriv->shortArrayCache.investment ); FREE_IF_NOT_NULL( pmPriv->shortArrayCache.profit ); FREE_IF_NOT_NULL( pmPriv->longArrayCache.investment ); FREE_IF_NOT_NULL( pmPriv->longArrayCache.profit ); FREE_IF_NOT_NULL( pmPriv->totalArrayCache.investment ); FREE_IF_NOT_NULL( pmPriv->totalArrayCache.profit ); /* Last thing that must be freed... */ TA_Free( toBeFreed ); } return TA_SUCCESS; }
static TA_RetCode TA_TraceGlobalInit( void **globalToAlloc ) { TA_TraceGlobal *global; #if !defined( TA_SINGLE_THREAD ) TA_RetCode retCode; #endif if( !globalToAlloc ) return TA_BAD_PARAM; *globalToAlloc = NULL; global = TA_Malloc( sizeof( TA_TraceGlobal ) ); if( !global ) return TA_ALLOC_ERR; memset( global, 0, sizeof( TA_TraceGlobal ) ); #if !defined( TA_SINGLE_THREAD ) /* Initialize the mutexes in a non-block state. */ retCode = TA_SemaInit( &global->callSema, 1 ); if( retCode != TA_SUCCESS ) { TA_Free( global ); return retCode; } retCode = TA_SemaInit( &global->fatalSema, 1 ); if( retCode != TA_SUCCESS ) { TA_SemaDestroy( &global->callSema ); TA_Free( global ); return retCode; } #endif #ifdef TA_DEBUG #if defined( TA_SINGLE_THREAD ) /* When single threaded, maintain a calling stack. */ global->callStack = TA_ListAlloc(); if( !global->callStack ) { TA_Free( global ); return TA_ALLOC_ERR; } #endif /* All function call and checkpoint are maintained in a dictionary. */ global->functionCalled = TA_DictAlloc( TA_DICT_KEY_ONE_STRING, freeTracePosition ); if( !global->functionCalled ) { #if !defined( TA_SINGLE_THREAD ) TA_SemaDestroy( &global->callSema ); TA_SemaDestroy( &global->fatalSema ); #else TA_ListFree( global->callStack ); #endif TA_Free( global ); return TA_ALLOC_ERR; } #endif /* Success, return the allocated memory to the caller. */ *globalToAlloc = global; return TA_SUCCESS; }
TA_RetCode TA_FileIndexAddCategoryData( TA_FileIndexPriv *data, TA_String *stringCategory, TA_FileIndexCategoryData **added ) { TA_PROLOG; TA_RetCode retCode; TA_FileIndexCategoryData *categoryData; unsigned int tmpInt; unsigned int categoryFound; /* Boolean */ TA_Libc *libHandle; TA_StringCache *stringCache; libHandle = data->libHandle; TA_TRACE_BEGIN( libHandle, TA_FileIndexAddCategoryData ); stringCache = TA_GetGlobalStringCache( libHandle ); TA_ASSERT( libHandle, data != NULL ); TA_ASSERT( libHandle, stringCategory != NULL ); /* Trap the case where the category is already added. */ categoryData = (TA_FileIndexCategoryData *)TA_ListAccessTail( data->listCategory ); categoryFound = 0; while( categoryData && !categoryFound ) { TA_ASSERT( libHandle, categoryData->string != NULL ); tmpInt = strcmp( TA_StringToChar( stringCategory ), TA_StringToChar( categoryData->string ) ); if( tmpInt == 0 ) categoryFound = 1; else categoryData = (TA_FileIndexCategoryData *)TA_ListAccessPrev( data->listCategory ); } if( !categoryFound ) { /* This is a new category, so allocate the TA_FileIndexCategoryData */ categoryData = (TA_FileIndexCategoryData *)TA_Malloc( libHandle, sizeof(TA_FileIndexCategoryData) ); if( !categoryData ) TA_TRACE_RETURN( TA_ALLOC_ERR ); /* Initialize the TA_FileIndexCategoryData */ categoryData->parent = data; if( stringCategory ) { categoryData->string = TA_StringDup( stringCache, stringCategory); /* String for this category. Can be NULL. */ if( !categoryData->string ) { TA_Free( libHandle, categoryData ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } } else categoryData->string = NULL; categoryData->listSymbol = TA_ListAlloc( libHandle ); if( !categoryData->listSymbol ) { if( categoryData->string ) TA_StringFree( stringCache, categoryData->string ); TA_Free( libHandle, categoryData ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } /* Add it to the TA_FileIndexPriv */ retCode = TA_ListAddTail( data->listCategory, categoryData ); if( retCode != TA_SUCCESS ) { TA_ListFree( categoryData->listSymbol ); if( categoryData->string ) TA_StringFree( stringCache, categoryData->string ); TA_Free( libHandle, categoryData ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } #if 0 printf( "**ADDING CATEGORY[%s]\n", TA_StringToChar( categoryData->string ) ); #endif } /* Return the address of the object representing that category. */ if( added ) *added = categoryData; TA_TRACE_RETURN( TA_SUCCESS ); }