// step2/memory_pool.cpp

#include <new>
#include "memory_pool.h"

void* MemoryPoolBase::allocSys(size_t uSize)
{
    void* pvResult = ::operator new(uSize, std::nothrow);
    if (!pvResult)
    {
        MemoryPoolSet::recycleMemoryPools();
        pvResult = ::operator new(uSize, std::nothrow);
    }
    return pvResult;
}

void MemoryPoolBase::deallocSys(void* pvReturn)
{
    ::operator delete(pvReturn);
}

MemoryPoolSet::MemoryPoolSet()
{
}

MemoryPoolSet::~MemoryPoolSet()
{
    while (!m_oMemoryPoolSet.empty())
    {
        // The destructor of a MemoryPool will remove itself from
        // the MemoryPoolSet.
        delete *m_oMemoryPoolSet.begin();
    }
}

MemoryPoolSet& MemoryPoolSet::instance()
{
    static MemoryPoolSet oInstance;
    return oInstance;
}

void MemoryPoolSet::recycleMemoryPools()
{
    instance().recycle();
}

void MemoryPoolSet::recycle()
{
    std::set<MemoryPoolBase*>::iterator end = m_oMemoryPoolSet.end();
    for (std::set<MemoryPoolBase*>::iterator
            i  = m_oMemoryPoolSet.begin();
            i != end; ++i)
    {
        (*i)->recycle();
    }
}