godfat (owner)

Revisions

gist: 53367 Download_button fork
public
Description:
object_pool.hpp.eruby
Public Clone URL: git://gist.github.com/53367.git
Embed All Files: show embed
C++ #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<% header_guard do %>
 
#include <boost/pool/object_pool.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
 
#define LOKI_CLASS_LEVEL_THREADING
#include <loki/Singleton.h>
 
namespace psc{ namespace utils{
 
template <typename T, typename UserAllocator = boost::default_user_allocator_new_delete>
class extended_object_pool: public boost::object_pool<T, UserAllocator>{
public:
    typedef typename boost::object_pool<T, UserAllocator>::element_type element_type;
    using boost::object_pool<T, UserAllocator>::construct;
 
<% for_template_parameters_within(4..5, []){ |args_list| %>
    template <%= template_parameters args_list %>
    element_type * construct(<%= forward_parameters args_list %>){
      element_type * const ret = this->malloc_mt();
      if (ret == 0)
        return ret;
      try { new (ret) element_type(<%= arguments args_list %>); }
      catch (...) { this->free_mt(ret); throw; }
      return ret;
    }
<% } %>
 
public:
    boost::mutex& mutex(){ return mutex_; }
 
private:
    element_type* malloc_mt(){
        boost::mutex::scoped_lock lock(mutex());
        return this->malloc();
    }
    void free_mt(element_type* p){
        boost::mutex::scoped_lock lock(mutex());
        return this->free(p);
    }
    boost::mutex mutex_;
};
 
template <class T>
class ObjectPool{
public:
    typedef typename T::pointer_type element_type;
 
public:
    static element_type create(){
        return element_type(SPool::Instance().construct(), Deleter());
    }
 
<% for_template_parameters_within(1..5, []){ |args_list| %>
    template <%= template_parameters args_list %>
    static element_type create(<%= forward_parameters args_list %>){
        return element_type(SPool::Instance().construct(<%= arguments args_list %>), Deleter());
    }
<% } %>
 
    static void destroy_all(){
        Loki::DeletableSingleton<pool_type>::GracefulDelete();
    }
 
private:
    typedef extended_object_pool<T> pool_type;
    typedef Loki::SingletonHolder<pool_type, Loki::CreateUsingNew, Loki::DeletableSingleton> SPool;
 
    static void destroy(T* t){
        SPool::Instance().destroy(t);
    }
    static bool is_from(T* t){
        return SPool::Instance().is_from(t);
    }
 
    friend class Deleter;
    class Deleter{
    public:
        typedef void result_type;
        typedef T* argument_type;
 
    public:
    // u.is_from(p) bool Returns true if p was allocated from u or may be returned as the result of a future allocation from u. Returns false if p was allocated from some other pool or may be returned as the result of a future allocation from some other pool. Otherwise, the return value is meaningless; note that this function may not be used to reliably test random pointer values.
        void operator()(argument_type p){
            boost::mutex::scoped_lock lock(SPool::Instance().mutex());
            if(ObjectPool<T>::is_from(p))
                ObjectPool<T>::destroy(p);
        }
    };
};
 
}} // end of namespace
 
<% end %>