//------------------------------------------------------------------------------------ /// At this stage in the app lifecycle all app and system references to resource /// should have been released. If the resource pool still has resources then this /// indicated leaks. //------------------------------------------------------------------------------------ void ResourcePool::Destroy() { ReleaseAllUnused(); bool error = false; for(auto& descEntry : m_descriptors) { for(auto itResource = descEntry.second.m_cachedResources.begin(); itResource != descEntry.second.m_cachedResources.end(); ++itResource) { //The pool is the sole owner so we can safely release the object CS_LOG_ERROR("Resource still in use: " + itResource->second->GetName()); error = true; } } if(error == true) { CS_LOG_FATAL("Resources are still in use. Indicates that there is leaky references"); } }
void OpMmapSegment::ForceReleaseAll(void) { #ifdef MEMORY_USE_LOCKING OpMemory::MallocLock(); #endif unsigned int idx = OP_MMAP_ANCHOR_COUNT + 1; while ( page_handle[idx].flag != OP_MMAP_FLAG_SENTINEL ) { UINT16 size = page_handle[idx].size; UINT16 flag = page_handle[idx].flag; OP_ASSERT(page_handle[idx + size - 1].size == size); OP_ASSERT(page_handle[idx + size - 1].flag == flag); if ( flag == OP_MMAP_FLAG_ALLOCATED ) { unsigned int idx2 = idx; while ( page_handle[idx2].flag == OP_MMAP_FLAG_ALLOCATED ) { UINT16 size2 = page_handle[idx2].size; #ifdef DEBUG_ENABLE_OPASSERT UINT16 flag2 = page_handle[idx2].flag; OP_ASSERT(page_handle[idx2 + size2 - 1].size == size2); OP_ASSERT(page_handle[idx2 + size2 - 1].flag == flag2); #endif #ifdef ENABLE_MEMORY_MANAGER OpMemoryClass type = (OpMemoryClass)page_handle[idx2].type; mm->Free(type, size2 * pagesize); #endif idx2 += size2; } unsigned int pages = idx2 - idx; unsigned int cls = ComputeSizeClass(pages); SetDetails(idx, pages, OP_MMAP_FLAG_UNUSED); #ifdef ENABLE_MEMORY_MANAGER mm->ForceAlloc((OpMemoryClass)unusedtype, pages * pagesize); #endif Link(OP_MMAP_UNUSED_SIZECLASS + cls, idx); allocated_pages -= pages; unused_pages += pages; size = pages; } idx += size; } // We should have no allocated pages any more OP_ASSERT(allocated_pages == 0); // The previously allocated ones should now be unused; release them all #ifdef MEMORY_USE_LOCKING ReleaseAllUnused(FALSE); #else ReleaseAllUnused(); #endif OP_ASSERT(unused_pages == 0); // // The last action is to release the memory used for the header and // page handles. After this operation, 'this' is no longer accessible. // OpMemoryClass type = (OpMemoryClass)hdrtype; if ( address_upper_handles != 0 ) { // Remove the upper handles, allocated on its own OpMemory_VirtualFree(mseg, address_upper_handles, size_upper_handles, type); } OpMemory_VirtualFree(mseg, mseg->address, pagesize * header_pages, type); #ifdef MEMORY_USE_LOCKING OpMemory::MallocUnlock(); #endif }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ void ResourcePool::OnMemoryWarning() { ReleaseAllUnused(); }