void _Mem_FreePool( mempool_t **pool, int musthave, int canthave, const char *filename, int fileline ) { mempool_t **chainAddress; #ifdef SHOW_NONFREED memheader_t *mem; #endif if( !( *pool ) ) return; if( musthave && ( ( ( *pool )->flags & musthave ) != musthave ) ) _Mem_Error( "Mem_FreePool: bad pool flags (musthave) (alloc at %s:%i)", filename, fileline ); if( canthave && ( ( *pool )->flags & canthave ) ) _Mem_Error( "Mem_FreePool: bad pool flags (canthave) (alloc at %s:%i)", filename, fileline ); // recurse into children // note that children will be freed no matter if their flags // do not match musthave\canthave pair while( ( *pool )->child ) { mempool_t *tmp = ( *pool )->child; _Mem_FreePool( &tmp, 0, 0, filename, fileline ); } assert( ( *pool )->sentinel1 == MEMHEADER_SENTINEL1 ); assert( ( *pool )->sentinel2 == MEMHEADER_SENTINEL1 ); if( ( *pool )->sentinel1 != MEMHEADER_SENTINEL1 ) _Mem_Error( "Mem_FreePool: trashed pool sentinel 1 (allocpool at %s:%i, freepool at %s:%i)", ( *pool )->filename, ( *pool )->fileline, filename, fileline ); if( ( *pool )->sentinel2 != MEMHEADER_SENTINEL1 ) _Mem_Error( "Mem_FreePool: trashed pool sentinel 2 (allocpool at %s:%i, freepool at %s:%i)", ( *pool )->filename, ( *pool )->fileline, filename, fileline ); #ifdef SHOW_NONFREED if( ( *pool )->chain ) Com_Printf( "Warning: Memory pool %s has resources that weren't freed:\n", ( *pool )->name ); for( mem = ( *pool )->chain; mem; mem = mem->next ) { Com_Printf( "%10i bytes allocated at %s:%i\n", mem->size, mem->filename, mem->fileline ); } #endif // unlink pool from chain if( ( *pool )->parent ) for( chainAddress = &( *pool )->parent->child; *chainAddress && *chainAddress != *pool; chainAddress = &( ( *chainAddress )->next ) ) ; else for( chainAddress = &poolChain; *chainAddress && *chainAddress != *pool; chainAddress = &( ( *chainAddress )->next ) ) ; if( *chainAddress != *pool ) _Mem_Error( "Mem_FreePool: pool already free (freepool at %s:%i)", filename, fileline ); while( ( *pool )->chain ) // free memory owned by the pool Mem_Free( (void *)( (qbyte *)( *pool )->chain + sizeof( memheader_t ) ) ); *chainAddress = ( *pool )->next; // free the pool itself #ifdef MEMTRASH memset( *pool, 0xBF, sizeof( mempool_t ) ); #endif free( *pool ); *pool = NULL; }
/** * @brief * @sa _Mem_CreatePool * @sa _Mem_FreePool */ void _Mem_DeletePool (memPool_t *pool, const char *fileName, const int fileLine) { if (!pool) return; /* Release all allocated memory */ _Mem_FreePool(pool, fileName, fileLine); /* Simple, yes? */ pool->inUse = false; pool->name[0] = '\0'; }
static void Irc_MemFreePool( const char *filename, int fileline ) { _Mem_FreePool( &irc_pool, 0, 0, filename, fileline ); }
/* * CL_CinModule_MemFreePool */ static void CL_CinModule_MemFreePool( mempool_t **pool, const char *filename, int fileline ) { _Mem_FreePool( pool, MEMPOOL_CINMODULE, 0, filename, fileline ); }
/* * CL_SoundModule_MemFreePool */ static void CL_SoundModule_MemFreePool( mempool_t **pool, const char *filename, int fileline ) { _Mem_FreePool( pool, MEMPOOL_SOUND, 0, filename, fileline ); }
static void Com_ScriptModule_MemFreePool( mempool_t **pool, const char *filename, int fileline ) { _Mem_FreePool( pool, MEMPOOL_ANGELSCRIPT, 0, filename, fileline ); }