steinwurf / recycle

Simple resource pool for recycling resources in C++
BSD 3-Clause "New" or "Revised" License
63 stars 23 forks source link

Custom object deallocater #18

Closed alexeys85 closed 6 years ago

alexeys85 commented 6 years ago

Hi! I'd like to provide a custom object deallocater. Which would be executed, for instance, upon freeing m_free_list .So I decided to expand existing recycle code:

void recycle(const value_ptr& resource)
 {
            if (m_recycle) {
                m_recycle(resource);
            }
            lock_type lock(m_mutex);
            if (m_free)
                m_free_list.push_back(value_ptr(resource.get(), m_free));
            else
                m_free_list.push_back(resource);
}

where m_free is a specified deallocater, like:

auto free = [](heavy_object* o)->void
 {
     free(o);
 };

But it doesn't seem to work right, because there is a double free error somewhere and I don't understand where...

mortenvp commented 6 years ago

Hi @alexeys85, sorry for the late response. I'm not sure I fully get your use-case. We do have support for a recycle function: https://github.com/steinwurf/recycle#id6

Would that not be sufficient to achieve the goal you are describing?

alexeys85 commented 6 years ago

Well, the purpose of the recycle is to just "recycle" a resource back to the pool. But, I want a custom function to deallocate resource then pool is going to be free. To delete resource not using standard delete function but with custom one.

mortenvp commented 6 years ago

Ah, I see. Yes, so basically providing a custom deleter.

I think a deleter can be "injected" in a custom allocate function e.g. adapted from the README:

#include <recycle/resource_pool.hpp>
#include <memory>

struct heavy_object
{
    heavy_object(uint32_t size);

   // ... some expensive resource
};

auto make = []()->std::shared_ptr<heavy_object>
     {
         return std::shared_ptr<heavy_object>(new heavy_object(300000U), 
             [](heavy_object* ptr){ .... });
     };

recycle::resource_pool<heavy_object> pool(make);

auto o1 = pool.allocate();
alexeys85 commented 6 years ago

Pool allocate function is already substitute shared_ptr deleter to the custom one to get resource back to the pool. So, injecting a deleter in a custom allocate function makes no sense because it will be substituted.

mortenvp commented 6 years ago

As far as I remember the original shared_ptr will remain the "real" owner. The original shared_ptr is also injected into the custom deleter used by the resource_pool. Did you try it out? I think it should work :)

alexeys85 commented 6 years ago

Sorry for inconvenience, it does work actually, thank you!

mortenvp commented 6 years ago

No problem :)