1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2008-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 <boost/interprocess/detail/workaround.hpp> |
12 | |
13 | #if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS) |
14 | |
15 | #include <boost/interprocess/allocators/allocator.hpp> |
16 | #include <boost/interprocess/containers/vector.hpp> |
17 | #include <boost/interprocess/managed_xsi_shared_memory.hpp> |
18 | #include <boost/interprocess/detail/file_wrapper.hpp> |
19 | #include <boost/interprocess/file_mapping.hpp> |
20 | #include <cstdio> |
21 | #include <string> |
22 | #include "get_process_id_name.hpp" |
23 | |
24 | using namespace boost::interprocess; |
25 | |
26 | void remove_shared_memory(const xsi_key &key) |
27 | { |
28 | BOOST_TRY{ |
29 | xsi_shared_memory xsi(open_only, key); |
30 | xsi_shared_memory::remove(shmid: xsi.get_shmid()); |
31 | } |
32 | BOOST_CATCH(interprocess_exception &e){ |
33 | if(e.get_error_code() != not_found_error) |
34 | BOOST_RETHROW |
35 | } BOOST_CATCH_END |
36 | } |
37 | |
38 | class xsi_shared_memory_remover |
39 | { |
40 | public: |
41 | xsi_shared_memory_remover(xsi_shared_memory &xsi_shm) |
42 | : xsi_shm_(xsi_shm) |
43 | {} |
44 | |
45 | ~xsi_shared_memory_remover() |
46 | { xsi_shared_memory::remove(shmid: xsi_shm_.get_shmid()); } |
47 | private: |
48 | xsi_shared_memory & xsi_shm_; |
49 | }; |
50 | |
51 | int main () |
52 | { |
53 | const std::size_t ShmemSize = 65536; |
54 | std::string filename = get_filename(); |
55 | const char *const ShmemName = filename.c_str(); |
56 | |
57 | file_mapping::remove(filename: ShmemName); |
58 | { ipcdetail::file_wrapper(create_only, ShmemName, read_write); } |
59 | |
60 | xsi_key key(ShmemName, static_cast<boost::uint8_t>(boost::interprocess::ipcdetail::get_current_system_highres_rand())); |
61 | file_mapping::remove(filename: ShmemName); |
62 | int shmid; |
63 | |
64 | //STL compatible allocator object for memory-mapped shmem |
65 | typedef allocator<int, managed_xsi_shared_memory::segment_manager> |
66 | allocator_int_t; |
67 | //A vector that uses that allocator |
68 | typedef boost::interprocess::vector<int, allocator_int_t> MyVect; |
69 | |
70 | { |
71 | //Remove the shmem it is already created |
72 | remove_shared_memory(key); |
73 | |
74 | const std::size_t max = 100; |
75 | void *array[max]; |
76 | //Named allocate capable shared memory allocator |
77 | managed_xsi_shared_memory shmem(create_only, key, ShmemSize); |
78 | shmid = shmem.get_shmid(); |
79 | std::size_t i; |
80 | //Let's allocate some memory |
81 | for(i = 0; i < max; ++i){ |
82 | array[i] = shmem.allocate(nbytes: i+1u); |
83 | } |
84 | |
85 | //Deallocate allocated memory |
86 | for(i = 0; i < max; ++i){ |
87 | shmem.deallocate(addr: array[i]); |
88 | } |
89 | } |
90 | |
91 | { |
92 | //Remove the shmem it is already created |
93 | xsi_shared_memory::remove(shmid); |
94 | |
95 | //Named allocate capable memory mapped shmem managed memory class |
96 | managed_xsi_shared_memory shmem(create_only, key, ShmemSize); |
97 | shmid = shmem.get_shmid(); |
98 | |
99 | //Construct the STL-like allocator with the segment manager |
100 | const allocator_int_t myallocator (shmem.get_segment_manager()); |
101 | |
102 | //Construct vector |
103 | MyVect *shmem_vect = shmem.construct<MyVect> (name: "MyVector" ) (myallocator); |
104 | |
105 | //Test that vector can be found via name |
106 | if(shmem_vect != shmem.find<MyVect>(name: "MyVector" ).first) |
107 | return -1; |
108 | |
109 | //Destroy and check it is not present |
110 | shmem.destroy<MyVect> (name: "MyVector" ); |
111 | if(0 != shmem.find<MyVect>(name: "MyVector" ).first) |
112 | return -1; |
113 | |
114 | //Construct a vector in the memory-mapped shmem |
115 | shmem_vect = shmem.construct<MyVect> (name: "MyVector" ) (myallocator); |
116 | } |
117 | { |
118 | //Map preexisting shmem again in memory |
119 | managed_xsi_shared_memory shmem(open_only, key); |
120 | shmid = shmem.get_shmid(); |
121 | |
122 | //Check vector is still there |
123 | MyVect *shmem_vect = shmem.find<MyVect>(name: "MyVector" ).first; |
124 | if(!shmem_vect) |
125 | return -1; |
126 | } |
127 | |
128 | |
129 | { |
130 | //Now destroy the vector |
131 | { |
132 | //Map preexisting shmem again in memory |
133 | managed_xsi_shared_memory shmem(open_only, key); |
134 | shmid = shmem.get_shmid(); |
135 | |
136 | //Destroy and check it is not present |
137 | shmem.destroy<MyVect>(name: "MyVector" ); |
138 | if(0 != shmem.find<MyVect>(name: "MyVector" ).first) |
139 | return -1; |
140 | } |
141 | |
142 | { |
143 | //Now test move semantics |
144 | managed_xsi_shared_memory original(open_only, key); |
145 | managed_xsi_shared_memory move_ctor(boost::move(t&: original)); |
146 | managed_xsi_shared_memory move_assign; |
147 | move_assign = boost::move(t&: move_ctor); |
148 | move_assign.swap(other&: original); |
149 | } |
150 | } |
151 | |
152 | xsi_shared_memory::remove(shmid); |
153 | return 0; |
154 | } |
155 | |
156 | #else |
157 | |
158 | int main() |
159 | { |
160 | return 0; |
161 | } |
162 | |
163 | #endif //#ifndef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS |
164 | |