Chris@16
|
1 //
|
Chris@16
|
2 // detail/object_pool.hpp
|
Chris@16
|
3 // ~~~~~~~~~~~~~~~~~~~~~~
|
Chris@16
|
4 //
|
Chris@101
|
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
Chris@16
|
6 //
|
Chris@16
|
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 //
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
|
Chris@16
|
12 #define BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
15 # pragma once
|
Chris@16
|
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/asio/detail/noncopyable.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/asio/detail/push_options.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 namespace boost {
|
Chris@16
|
23 namespace asio {
|
Chris@16
|
24 namespace detail {
|
Chris@16
|
25
|
Chris@16
|
26 template <typename Object>
|
Chris@16
|
27 class object_pool;
|
Chris@16
|
28
|
Chris@16
|
29 class object_pool_access
|
Chris@16
|
30 {
|
Chris@16
|
31 public:
|
Chris@16
|
32 template <typename Object>
|
Chris@16
|
33 static Object* create()
|
Chris@16
|
34 {
|
Chris@16
|
35 return new Object;
|
Chris@16
|
36 }
|
Chris@16
|
37
|
Chris@16
|
38 template <typename Object>
|
Chris@16
|
39 static void destroy(Object* o)
|
Chris@16
|
40 {
|
Chris@16
|
41 delete o;
|
Chris@16
|
42 }
|
Chris@16
|
43
|
Chris@16
|
44 template <typename Object>
|
Chris@16
|
45 static Object*& next(Object* o)
|
Chris@16
|
46 {
|
Chris@16
|
47 return o->next_;
|
Chris@16
|
48 }
|
Chris@16
|
49
|
Chris@16
|
50 template <typename Object>
|
Chris@16
|
51 static Object*& prev(Object* o)
|
Chris@16
|
52 {
|
Chris@16
|
53 return o->prev_;
|
Chris@16
|
54 }
|
Chris@16
|
55 };
|
Chris@16
|
56
|
Chris@16
|
57 template <typename Object>
|
Chris@16
|
58 class object_pool
|
Chris@16
|
59 : private noncopyable
|
Chris@16
|
60 {
|
Chris@16
|
61 public:
|
Chris@16
|
62 // Constructor.
|
Chris@16
|
63 object_pool()
|
Chris@16
|
64 : live_list_(0),
|
Chris@16
|
65 free_list_(0)
|
Chris@16
|
66 {
|
Chris@16
|
67 }
|
Chris@16
|
68
|
Chris@16
|
69 // Destructor destroys all objects.
|
Chris@16
|
70 ~object_pool()
|
Chris@16
|
71 {
|
Chris@16
|
72 destroy_list(live_list_);
|
Chris@16
|
73 destroy_list(free_list_);
|
Chris@16
|
74 }
|
Chris@16
|
75
|
Chris@16
|
76 // Get the object at the start of the live list.
|
Chris@16
|
77 Object* first()
|
Chris@16
|
78 {
|
Chris@16
|
79 return live_list_;
|
Chris@16
|
80 }
|
Chris@16
|
81
|
Chris@16
|
82 // Allocate a new object.
|
Chris@16
|
83 Object* alloc()
|
Chris@16
|
84 {
|
Chris@16
|
85 Object* o = free_list_;
|
Chris@16
|
86 if (o)
|
Chris@16
|
87 free_list_ = object_pool_access::next(free_list_);
|
Chris@16
|
88 else
|
Chris@16
|
89 o = object_pool_access::create<Object>();
|
Chris@16
|
90
|
Chris@16
|
91 object_pool_access::next(o) = live_list_;
|
Chris@16
|
92 object_pool_access::prev(o) = 0;
|
Chris@16
|
93 if (live_list_)
|
Chris@16
|
94 object_pool_access::prev(live_list_) = o;
|
Chris@16
|
95 live_list_ = o;
|
Chris@16
|
96
|
Chris@16
|
97 return o;
|
Chris@16
|
98 }
|
Chris@16
|
99
|
Chris@16
|
100 // Free an object. Moves it to the free list. No destructors are run.
|
Chris@16
|
101 void free(Object* o)
|
Chris@16
|
102 {
|
Chris@16
|
103 if (live_list_ == o)
|
Chris@16
|
104 live_list_ = object_pool_access::next(o);
|
Chris@16
|
105
|
Chris@16
|
106 if (object_pool_access::prev(o))
|
Chris@16
|
107 {
|
Chris@16
|
108 object_pool_access::next(object_pool_access::prev(o))
|
Chris@16
|
109 = object_pool_access::next(o);
|
Chris@16
|
110 }
|
Chris@16
|
111
|
Chris@16
|
112 if (object_pool_access::next(o))
|
Chris@16
|
113 {
|
Chris@16
|
114 object_pool_access::prev(object_pool_access::next(o))
|
Chris@16
|
115 = object_pool_access::prev(o);
|
Chris@16
|
116 }
|
Chris@16
|
117
|
Chris@16
|
118 object_pool_access::next(o) = free_list_;
|
Chris@16
|
119 object_pool_access::prev(o) = 0;
|
Chris@16
|
120 free_list_ = o;
|
Chris@16
|
121 }
|
Chris@16
|
122
|
Chris@16
|
123 private:
|
Chris@16
|
124 // Helper function to destroy all elements in a list.
|
Chris@16
|
125 void destroy_list(Object* list)
|
Chris@16
|
126 {
|
Chris@16
|
127 while (list)
|
Chris@16
|
128 {
|
Chris@16
|
129 Object* o = list;
|
Chris@16
|
130 list = object_pool_access::next(o);
|
Chris@16
|
131 object_pool_access::destroy(o);
|
Chris@16
|
132 }
|
Chris@16
|
133 }
|
Chris@16
|
134
|
Chris@16
|
135 // The list of live objects.
|
Chris@16
|
136 Object* live_list_;
|
Chris@16
|
137
|
Chris@16
|
138 // The free list.
|
Chris@16
|
139 Object* free_list_;
|
Chris@16
|
140 };
|
Chris@16
|
141
|
Chris@16
|
142 } // namespace detail
|
Chris@16
|
143 } // namespace asio
|
Chris@16
|
144 } // namespace boost
|
Chris@16
|
145
|
Chris@16
|
146 #include <boost/asio/detail/pop_options.hpp>
|
Chris@16
|
147
|
Chris@16
|
148 #endif // BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
|