• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 
11 #include <memory>
12 #include <deque>
13 #include <iostream>
14 #include <list>
15 
16 #include <boost/interprocess/managed_shared_memory.hpp>
17 #include <boost/interprocess/containers/deque.hpp>
18 #include <boost/interprocess/indexes/flat_map_index.hpp>
19 #include "print_container.hpp"
20 #include "check_equal_containers.hpp"
21 #include "dummy_test_allocator.hpp"
22 #include "movable_int.hpp"
23 #include <boost/interprocess/allocators/allocator.hpp>
24 #include "allocator_v1.hpp"
25 #include <boost/interprocess/exceptions.hpp>
26 #include <boost/move/utility_core.hpp>
27 #include <boost/interprocess/detail/mpl.hpp>
28 #include <boost/interprocess/detail/type_traits.hpp>
29 #include <string>
30 #include "get_process_id_name.hpp"
31 #include "emplace_test.hpp"
32 
33 ///////////////////////////////////////////////////////////////////
34 //                                                               //
35 //  This example repeats the same operations with std::deque and //
36 //  shmem_deque using the node allocator                         //
37 //  and compares the values of both containers                   //
38 //                                                               //
39 ///////////////////////////////////////////////////////////////////
40 
41 using namespace boost::interprocess;
42 
43 //Function to check if both sets are equal
44 template<class V1, class V2>
copyable_only(V1 *,V2 *,ipcdetail::false_type)45 bool copyable_only(V1 *, V2 *, ipcdetail::false_type)
46 {
47    return true;
48 }
49 
50 //Function to check if both sets are equal
51 template<class V1, class V2>
copyable_only(V1 * shmdeque,V2 * stddeque,ipcdetail::true_type)52 bool copyable_only(V1 *shmdeque, V2 *stddeque, ipcdetail::true_type)
53 {
54    typedef typename V1::value_type IntType;
55    std::size_t size = shmdeque->size();
56    stddeque->insert(stddeque->end(), 50, 1);
57    shmdeque->insert(shmdeque->end(), 50, IntType(1));
58    if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
59    {
60       IntType move_me(1);
61       stddeque->insert(stddeque->begin()+size/2, 50, 1);
62       shmdeque->insert(shmdeque->begin()+size/2, 50, boost::move(move_me));
63       if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
64    }
65    {
66       IntType move_me(2);
67       shmdeque->assign(shmdeque->size()/2, boost::move(move_me));
68       stddeque->assign(stddeque->size()/2, 2);
69       if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
70    }
71    {
72       IntType move_me(1);
73       stddeque->clear();
74       shmdeque->clear();
75       stddeque->insert(stddeque->begin(), 50, 1);
76       shmdeque->insert(shmdeque->begin(), 50, boost::move(move_me));
77       if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
78       stddeque->insert(stddeque->begin()+20, 50, 1);
79       shmdeque->insert(shmdeque->begin()+20, 50, boost::move(move_me));
80       if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
81       stddeque->insert(stddeque->begin()+20, 20, 1);
82       shmdeque->insert(shmdeque->begin()+20, 20, boost::move(move_me));
83       if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
84    }
85    {
86       IntType move_me(1);
87       stddeque->clear();
88       shmdeque->clear();
89       stddeque->insert(stddeque->end(), 50, 1);
90       shmdeque->insert(shmdeque->end(), 50, boost::move(move_me));
91       if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
92       stddeque->insert(stddeque->end()-20, 50, 1);
93       shmdeque->insert(shmdeque->end()-20, 50, boost::move(move_me));
94       if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
95       stddeque->insert(stddeque->end()-20, 20, 1);
96       shmdeque->insert(shmdeque->end()-20, 20, boost::move(move_me));
97       if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
98    }
99 
100    return true;
101 }
102 
103 
104 template<class IntType, template<class T, class SegmentManager> class AllocatorType >
do_test()105 bool do_test()
106 {
107    //Customize managed_shared_memory class
108    typedef basic_managed_shared_memory
109       <char,
110       //simple_seq_fit<mutex_family>,
111       rbtree_best_fit<mutex_family>,
112       //flat_map_index
113       iset_index
114       > my_managed_shared_memory;
115 
116    //Alias AllocatorType type
117    typedef AllocatorType<IntType, my_managed_shared_memory::segment_manager>
118       shmem_allocator_t;
119 
120    //Alias deque types
121    typedef deque<IntType, shmem_allocator_t>   MyShmDeque;
122    typedef std::deque<int>                     MyStdDeque;
123    const int Memsize = 65536;
124    const char *const shMemName = test::get_process_id_name();
125    const int max = 100;
126 
127    /*try*/{
128       shared_memory_object::remove(shMemName);
129 
130       //Create shared memory
131       my_managed_shared_memory segment(create_only, shMemName, Memsize);
132 
133       segment.reserve_named_objects(100);
134 
135       //Shared memory allocator must be always be initialized
136       //since it has no default constructor
137       MyShmDeque *shmdeque = segment.template construct<MyShmDeque>("MyShmDeque")
138                               (segment.get_segment_manager());
139 
140       MyStdDeque *stddeque = new MyStdDeque;
141 
142       /*try*/{
143          //Compare several shared memory deque operations with std::deque
144          for(int i = 0; i < max*50; ++i){
145             IntType move_me(i);
146             shmdeque->insert(shmdeque->end(), boost::move(move_me));
147             stddeque->insert(stddeque->end(), i);
148             shmdeque->insert(shmdeque->end(), IntType(i));
149             stddeque->insert(stddeque->end(), int(i));
150          }
151          if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
152 
153          shmdeque->clear();
154          stddeque->clear();
155 
156          for(int i = 0; i < max*50; ++i){
157             IntType move_me(i);
158             shmdeque->push_back(boost::move(move_me));
159             stddeque->push_back(i);
160             shmdeque->push_back(IntType(i));
161             stddeque->push_back(i);
162          }
163          if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
164 
165          shmdeque->clear();
166          stddeque->clear();
167 
168          for(int i = 0; i < max*50; ++i){
169             IntType move_me(i);
170             shmdeque->push_front(boost::move(move_me));
171             stddeque->push_front(i);
172             shmdeque->push_front(IntType(i));
173             stddeque->push_front(int(i));
174          }
175          if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
176 
177          typename MyShmDeque::iterator it;
178          typename MyShmDeque::const_iterator cit = it;
179          (void)cit;
180 
181          shmdeque->erase(shmdeque->begin()++);
182          stddeque->erase(stddeque->begin()++);
183          if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
184 
185          shmdeque->erase(shmdeque->begin());
186          stddeque->erase(stddeque->begin());
187          if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
188 
189          {
190             //Initialize values
191             IntType aux_vect[50];
192             for(int i = 0; i < 50; ++i){
193                IntType move_me (-1);
194                aux_vect[i] = boost::move(move_me);
195             }
196             int aux_vect2[50];
197             for(int i = 0; i < 50; ++i){
198                aux_vect2[i] = -1;
199             }
200 
201             shmdeque->insert(shmdeque->end()
202                               ,::boost::make_move_iterator(&aux_vect[0])
203                               ,::boost::make_move_iterator(aux_vect + 50));
204             stddeque->insert(stddeque->end(), aux_vect2, aux_vect2 + 50);
205             if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
206 
207             for(int i = 0, j = static_cast<int>(shmdeque->size()); i < j; ++i){
208                shmdeque->erase(shmdeque->begin());
209                stddeque->erase(stddeque->begin());
210             }
211             if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
212          }
213          {
214             IntType aux_vect[50];
215             for(int i = 0; i < 50; ++i){
216                IntType move_me(-1);
217                aux_vect[i] = boost::move(move_me);
218             }
219             int aux_vect2[50];
220             for(int i = 0; i < 50; ++i){
221                aux_vect2[i] = -1;
222             }
223             shmdeque->insert(shmdeque->begin()
224                               ,::boost::make_move_iterator(&aux_vect[0])
225                               ,::boost::make_move_iterator(aux_vect + 50));
226             stddeque->insert(stddeque->begin(), aux_vect2, aux_vect2 + 50);
227             if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
228          }
229 
230          if(!copyable_only(shmdeque, stddeque
231                         ,ipcdetail::bool_<!ipcdetail::is_same<IntType, test::movable_int>::value>())){
232             return false;
233          }
234 
235          shmdeque->erase(shmdeque->begin());
236          stddeque->erase(stddeque->begin());
237 
238          if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
239 
240          for(int i = 0; i < max; ++i){
241             IntType move_me(i);
242             shmdeque->insert(shmdeque->begin(), boost::move(move_me));
243             stddeque->insert(stddeque->begin(), i);
244          }
245          if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
246 
247          //Test insertion from list
248          {
249             std::list<int> l(50, int(1));
250             shmdeque->insert(shmdeque->begin(), l.begin(), l.end());
251             stddeque->insert(stddeque->begin(), l.begin(), l.end());
252             if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
253             shmdeque->assign(l.begin(), l.end());
254             stddeque->assign(l.begin(), l.end());
255             if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
256          }
257 
258          shmdeque->resize(100);
259          stddeque->resize(100);
260          if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
261 
262          shmdeque->resize(200);
263          stddeque->resize(200);
264          if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
265 
266          segment.template destroy<MyShmDeque>("MyShmDeque");
267          delete stddeque;
268          segment.shrink_to_fit_indexes();
269 
270          if(!segment.all_memory_deallocated())
271             return false;
272       }/*
273       catch(std::exception &ex){
274          std::cout << ex.what() << std::endl;
275          return false;
276       }*/
277 
278       std::cout << std::endl << "Test OK!" << std::endl;
279    }/*
280    catch(...){
281       shared_memory_object::remove(shMemName);
282       throw;
283    }*/
284    shared_memory_object::remove(shMemName);
285    return true;
286 }
287 
main()288 int main ()
289 {
290    if(!do_test<int, allocator>())
291       return 1;
292 
293    if(!do_test<test::movable_int, allocator>())
294       return 1;
295 
296    if(!do_test<test::copyable_int, allocator>())
297       return 1;
298 
299    if(!do_test<int, test::allocator_v1>())
300       return 1;
301 
302    const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
303 
304    if(!boost::interprocess::test::test_emplace
305       < deque<test::EmplaceInt>, Options>())
306       return 1;
307 
308    return 0;
309 }
310