Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 // See http://www.boost.org/libs/interprocess for documentation.
|
Chris@16
|
8 //
|
Chris@16
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP
|
Chris@16
|
12 #define BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP
|
Chris@16
|
13
|
Chris@101
|
14 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
15 # include <boost/config.hpp>
|
Chris@101
|
16 #endif
|
Chris@101
|
17 #
|
Chris@101
|
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@101
|
19 # pragma once
|
Chris@101
|
20 #endif
|
Chris@101
|
21
|
Chris@16
|
22 #include <boost/interprocess/detail/config_begin.hpp>
|
Chris@16
|
23 #include <boost/interprocess/detail/workaround.hpp>
|
Chris@16
|
24 #include <boost/interprocess/creation_tags.hpp>
|
Chris@16
|
25 #include <boost/interprocess/exceptions.hpp>
|
Chris@101
|
26 #include <boost/move/utility_core.hpp>
|
Chris@16
|
27 #include <boost/interprocess/interprocess_fwd.hpp>
|
Chris@16
|
28 #include <boost/interprocess/exceptions.hpp>
|
Chris@16
|
29 #include <boost/interprocess/detail/os_file_functions.hpp>
|
Chris@101
|
30 #include <boost/interprocess/detail/shared_dir_helpers.hpp>
|
Chris@16
|
31 #include <boost/interprocess/permissions.hpp>
|
Chris@101
|
32 #include <boost/move/adl_move_swap.hpp>
|
Chris@16
|
33 #include <cstddef>
|
Chris@16
|
34 #include <string>
|
Chris@16
|
35
|
Chris@101
|
36 #if defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
|
Chris@16
|
37 # include <fcntl.h> //O_CREAT, O_*...
|
Chris@16
|
38 # include <sys/mman.h> //shm_xxx
|
Chris@16
|
39 # include <unistd.h> //ftruncate, close
|
Chris@16
|
40 # include <sys/stat.h> //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
|
Chris@16
|
41 # if defined(BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
Chris@16
|
42 # if defined(__FreeBSD__)
|
Chris@16
|
43 # include <sys/sysctl.h>
|
Chris@16
|
44 # endif
|
Chris@16
|
45 # endif
|
Chris@16
|
46 #else
|
Chris@16
|
47 //
|
Chris@16
|
48 #endif
|
Chris@16
|
49
|
Chris@16
|
50 //!\file
|
Chris@16
|
51 //!Describes a shared memory object management class.
|
Chris@16
|
52
|
Chris@16
|
53 namespace boost {
|
Chris@16
|
54 namespace interprocess {
|
Chris@16
|
55
|
Chris@16
|
56 //!A class that wraps a shared memory mapping that can be used to
|
Chris@16
|
57 //!create mapped regions from the mapped files
|
Chris@16
|
58 class shared_memory_object
|
Chris@16
|
59 {
|
Chris@101
|
60 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
61 //Non-copyable and non-assignable
|
Chris@16
|
62 BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_memory_object)
|
Chris@101
|
63 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
64
|
Chris@16
|
65 public:
|
Chris@16
|
66 //!Default constructor. Represents an empty shared_memory_object.
|
Chris@16
|
67 shared_memory_object();
|
Chris@16
|
68
|
Chris@16
|
69 //!Creates a shared memory object with name "name" and mode "mode", with the access mode "mode"
|
Chris@16
|
70 //!If the file previously exists, throws an error.*/
|
Chris@16
|
71 shared_memory_object(create_only_t, const char *name, mode_t mode, const permissions &perm = permissions())
|
Chris@16
|
72 { this->priv_open_or_create(ipcdetail::DoCreate, name, mode, perm); }
|
Chris@16
|
73
|
Chris@16
|
74 //!Tries to create a shared memory object with name "name" and mode "mode", with the
|
Chris@16
|
75 //!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
|
Chris@16
|
76 //!Otherwise throws an error.
|
Chris@16
|
77 shared_memory_object(open_or_create_t, const char *name, mode_t mode, const permissions &perm = permissions())
|
Chris@16
|
78 { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, perm); }
|
Chris@16
|
79
|
Chris@16
|
80 //!Tries to open a shared memory object with name "name", with the access mode "mode".
|
Chris@16
|
81 //!If the file does not previously exist, it throws an error.
|
Chris@16
|
82 shared_memory_object(open_only_t, const char *name, mode_t mode)
|
Chris@16
|
83 { this->priv_open_or_create(ipcdetail::DoOpen, name, mode, permissions()); }
|
Chris@16
|
84
|
Chris@16
|
85 //!Moves the ownership of "moved"'s shared memory object to *this.
|
Chris@16
|
86 //!After the call, "moved" does not represent any shared memory object.
|
Chris@16
|
87 //!Does not throw
|
Chris@16
|
88 shared_memory_object(BOOST_RV_REF(shared_memory_object) moved)
|
Chris@16
|
89 : m_handle(file_handle_t(ipcdetail::invalid_file()))
|
Chris@16
|
90 , m_mode(read_only)
|
Chris@16
|
91 { this->swap(moved); }
|
Chris@16
|
92
|
Chris@16
|
93 //!Moves the ownership of "moved"'s shared memory to *this.
|
Chris@16
|
94 //!After the call, "moved" does not represent any shared memory.
|
Chris@16
|
95 //!Does not throw
|
Chris@16
|
96 shared_memory_object &operator=(BOOST_RV_REF(shared_memory_object) moved)
|
Chris@16
|
97 {
|
Chris@16
|
98 shared_memory_object tmp(boost::move(moved));
|
Chris@16
|
99 this->swap(tmp);
|
Chris@16
|
100 return *this;
|
Chris@16
|
101 }
|
Chris@16
|
102
|
Chris@16
|
103 //!Swaps the shared_memory_objects. Does not throw
|
Chris@16
|
104 void swap(shared_memory_object &moved);
|
Chris@16
|
105
|
Chris@16
|
106 //!Erases a shared memory object from the system.
|
Chris@16
|
107 //!Returns false on error. Never throws
|
Chris@16
|
108 static bool remove(const char *name);
|
Chris@16
|
109
|
Chris@16
|
110 //!Sets the size of the shared memory mapping
|
Chris@16
|
111 void truncate(offset_t length);
|
Chris@16
|
112
|
Chris@16
|
113 //!Destroys *this and indicates that the calling process is finished using
|
Chris@16
|
114 //!the resource. All mapped regions are still
|
Chris@16
|
115 //!valid after destruction. The destructor function will deallocate
|
Chris@16
|
116 //!any system resources allocated by the system for use by this process for
|
Chris@16
|
117 //!this resource. The resource can still be opened again calling
|
Chris@16
|
118 //!the open constructor overload. To erase the resource from the system
|
Chris@16
|
119 //!use remove().
|
Chris@16
|
120 ~shared_memory_object();
|
Chris@16
|
121
|
Chris@16
|
122 //!Returns the name of the shared memory object.
|
Chris@16
|
123 const char *get_name() const;
|
Chris@16
|
124
|
Chris@16
|
125 //!Returns true if the size of the shared memory object
|
Chris@16
|
126 //!can be obtained and writes the size in the passed reference
|
Chris@16
|
127 bool get_size(offset_t &size) const;
|
Chris@16
|
128
|
Chris@16
|
129 //!Returns access mode
|
Chris@16
|
130 mode_t get_mode() const;
|
Chris@16
|
131
|
Chris@16
|
132 //!Returns mapping handle. Never throws.
|
Chris@16
|
133 mapping_handle_t get_mapping_handle() const;
|
Chris@16
|
134
|
Chris@101
|
135 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
136 private:
|
Chris@16
|
137
|
Chris@16
|
138 //!Closes a previously opened file mapping. Never throws.
|
Chris@16
|
139 void priv_close();
|
Chris@16
|
140
|
Chris@101
|
141 //!Opens or creates a shared memory object.
|
Chris@16
|
142 bool priv_open_or_create(ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm);
|
Chris@16
|
143
|
Chris@16
|
144 file_handle_t m_handle;
|
Chris@16
|
145 mode_t m_mode;
|
Chris@16
|
146 std::string m_filename;
|
Chris@101
|
147 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
148 };
|
Chris@16
|
149
|
Chris@101
|
150 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
151
|
Chris@16
|
152 inline shared_memory_object::shared_memory_object()
|
Chris@16
|
153 : m_handle(file_handle_t(ipcdetail::invalid_file()))
|
Chris@16
|
154 , m_mode(read_only)
|
Chris@16
|
155 {}
|
Chris@16
|
156
|
Chris@16
|
157 inline shared_memory_object::~shared_memory_object()
|
Chris@16
|
158 { this->priv_close(); }
|
Chris@16
|
159
|
Chris@16
|
160
|
Chris@16
|
161 inline const char *shared_memory_object::get_name() const
|
Chris@16
|
162 { return m_filename.c_str(); }
|
Chris@16
|
163
|
Chris@16
|
164 inline bool shared_memory_object::get_size(offset_t &size) const
|
Chris@16
|
165 { return ipcdetail::get_file_size((file_handle_t)m_handle, size); }
|
Chris@16
|
166
|
Chris@16
|
167 inline void shared_memory_object::swap(shared_memory_object &other)
|
Chris@16
|
168 {
|
Chris@101
|
169 boost::adl_move_swap(m_handle, other.m_handle);
|
Chris@101
|
170 boost::adl_move_swap(m_mode, other.m_mode);
|
Chris@16
|
171 m_filename.swap(other.m_filename);
|
Chris@16
|
172 }
|
Chris@16
|
173
|
Chris@16
|
174 inline mapping_handle_t shared_memory_object::get_mapping_handle() const
|
Chris@16
|
175 {
|
Chris@16
|
176 return ipcdetail::mapping_handle_from_file_handle(m_handle);
|
Chris@16
|
177 }
|
Chris@16
|
178
|
Chris@16
|
179 inline mode_t shared_memory_object::get_mode() const
|
Chris@16
|
180 { return m_mode; }
|
Chris@16
|
181
|
Chris@16
|
182 #if !defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
|
Chris@16
|
183
|
Chris@16
|
184 inline bool shared_memory_object::priv_open_or_create
|
Chris@16
|
185 (ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm)
|
Chris@16
|
186 {
|
Chris@16
|
187 m_filename = filename;
|
Chris@16
|
188 std::string shmfile;
|
Chris@101
|
189 ipcdetail::create_shared_dir_cleaning_old_and_get_filepath(filename, shmfile);
|
Chris@16
|
190
|
Chris@16
|
191 //Set accesses
|
Chris@16
|
192 if (mode != read_write && mode != read_only){
|
Chris@16
|
193 error_info err = other_error;
|
Chris@16
|
194 throw interprocess_exception(err);
|
Chris@16
|
195 }
|
Chris@16
|
196
|
Chris@16
|
197 switch(type){
|
Chris@16
|
198 case ipcdetail::DoOpen:
|
Chris@16
|
199 m_handle = ipcdetail::open_existing_file(shmfile.c_str(), mode, true);
|
Chris@16
|
200 break;
|
Chris@16
|
201 case ipcdetail::DoCreate:
|
Chris@16
|
202 m_handle = ipcdetail::create_new_file(shmfile.c_str(), mode, perm, true);
|
Chris@16
|
203 break;
|
Chris@16
|
204 case ipcdetail::DoOpenOrCreate:
|
Chris@16
|
205 m_handle = ipcdetail::create_or_open_file(shmfile.c_str(), mode, perm, true);
|
Chris@16
|
206 break;
|
Chris@16
|
207 default:
|
Chris@16
|
208 {
|
Chris@16
|
209 error_info err = other_error;
|
Chris@16
|
210 throw interprocess_exception(err);
|
Chris@16
|
211 }
|
Chris@16
|
212 }
|
Chris@16
|
213
|
Chris@16
|
214 //Check for error
|
Chris@16
|
215 if(m_handle == ipcdetail::invalid_file()){
|
Chris@16
|
216 error_info err = system_error_code();
|
Chris@16
|
217 this->priv_close();
|
Chris@16
|
218 throw interprocess_exception(err);
|
Chris@16
|
219 }
|
Chris@16
|
220
|
Chris@16
|
221 m_mode = mode;
|
Chris@16
|
222 return true;
|
Chris@16
|
223 }
|
Chris@16
|
224
|
Chris@16
|
225 inline bool shared_memory_object::remove(const char *filename)
|
Chris@16
|
226 {
|
Chris@16
|
227 try{
|
Chris@16
|
228 //Make sure a temporary path is created for shared memory
|
Chris@16
|
229 std::string shmfile;
|
Chris@101
|
230 ipcdetail::shared_filepath(filename, shmfile);
|
Chris@16
|
231 return ipcdetail::delete_file(shmfile.c_str());
|
Chris@16
|
232 }
|
Chris@16
|
233 catch(...){
|
Chris@16
|
234 return false;
|
Chris@16
|
235 }
|
Chris@16
|
236 }
|
Chris@16
|
237
|
Chris@16
|
238 inline void shared_memory_object::truncate(offset_t length)
|
Chris@16
|
239 {
|
Chris@16
|
240 if(!ipcdetail::truncate_file(m_handle, length)){
|
Chris@16
|
241 error_info err = system_error_code();
|
Chris@16
|
242 throw interprocess_exception(err);
|
Chris@16
|
243 }
|
Chris@16
|
244 }
|
Chris@16
|
245
|
Chris@16
|
246 inline void shared_memory_object::priv_close()
|
Chris@16
|
247 {
|
Chris@16
|
248 if(m_handle != ipcdetail::invalid_file()){
|
Chris@16
|
249 ipcdetail::close_file(m_handle);
|
Chris@16
|
250 m_handle = ipcdetail::invalid_file();
|
Chris@16
|
251 }
|
Chris@16
|
252 }
|
Chris@16
|
253
|
Chris@16
|
254 #else //!defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
|
Chris@16
|
255
|
Chris@16
|
256 namespace shared_memory_object_detail {
|
Chris@16
|
257
|
Chris@16
|
258 #ifdef BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
|
Chris@16
|
259
|
Chris@16
|
260 #if defined(__FreeBSD__)
|
Chris@16
|
261
|
Chris@16
|
262 inline bool use_filesystem_based_posix()
|
Chris@16
|
263 {
|
Chris@16
|
264 int jailed = 0;
|
Chris@16
|
265 std::size_t len = sizeof(jailed);
|
Chris@16
|
266 ::sysctlbyname("security.jail.jailed", &jailed, &len, NULL, 0);
|
Chris@16
|
267 return jailed != 0;
|
Chris@16
|
268 }
|
Chris@16
|
269
|
Chris@16
|
270 #else
|
Chris@16
|
271 #error "Not supported platform for BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY"
|
Chris@16
|
272 #endif
|
Chris@16
|
273
|
Chris@16
|
274 #endif
|
Chris@16
|
275
|
Chris@16
|
276 } //shared_memory_object_detail
|
Chris@16
|
277
|
Chris@16
|
278 inline bool shared_memory_object::priv_open_or_create
|
Chris@16
|
279 (ipcdetail::create_enum_t type,
|
Chris@16
|
280 const char *filename,
|
Chris@16
|
281 mode_t mode, const permissions &perm)
|
Chris@16
|
282 {
|
Chris@16
|
283 #if defined(BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
Chris@16
|
284 const bool add_leading_slash = false;
|
Chris@16
|
285 #elif defined(BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
Chris@16
|
286 const bool add_leading_slash = !shared_memory_object_detail::use_filesystem_based_posix();
|
Chris@16
|
287 #else
|
Chris@16
|
288 const bool add_leading_slash = true;
|
Chris@16
|
289 #endif
|
Chris@16
|
290 if(add_leading_slash){
|
Chris@16
|
291 ipcdetail::add_leading_slash(filename, m_filename);
|
Chris@16
|
292 }
|
Chris@16
|
293 else{
|
Chris@101
|
294 ipcdetail::create_shared_dir_cleaning_old_and_get_filepath(filename, m_filename);
|
Chris@16
|
295 }
|
Chris@16
|
296
|
Chris@16
|
297 //Create new mapping
|
Chris@16
|
298 int oflag = 0;
|
Chris@16
|
299 if(mode == read_only){
|
Chris@16
|
300 oflag |= O_RDONLY;
|
Chris@16
|
301 }
|
Chris@16
|
302 else if(mode == read_write){
|
Chris@16
|
303 oflag |= O_RDWR;
|
Chris@16
|
304 }
|
Chris@16
|
305 else{
|
Chris@16
|
306 error_info err(mode_error);
|
Chris@16
|
307 throw interprocess_exception(err);
|
Chris@16
|
308 }
|
Chris@16
|
309 int unix_perm = perm.get_permissions();
|
Chris@16
|
310
|
Chris@16
|
311 switch(type){
|
Chris@16
|
312 case ipcdetail::DoOpen:
|
Chris@16
|
313 {
|
Chris@16
|
314 //No oflag addition
|
Chris@16
|
315 m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
|
Chris@16
|
316 }
|
Chris@16
|
317 break;
|
Chris@16
|
318 case ipcdetail::DoCreate:
|
Chris@16
|
319 {
|
Chris@16
|
320 oflag |= (O_CREAT | O_EXCL);
|
Chris@16
|
321 m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
|
Chris@16
|
322 if(m_handle >= 0){
|
Chris@16
|
323 ::fchmod(m_handle, unix_perm);
|
Chris@16
|
324 }
|
Chris@16
|
325 }
|
Chris@16
|
326 break;
|
Chris@16
|
327 case ipcdetail::DoOpenOrCreate:
|
Chris@16
|
328 {
|
Chris@16
|
329 //We need a create/open loop to change permissions correctly using fchmod, since
|
Chris@16
|
330 //with "O_CREAT" only we don't know if we've created or opened the shm.
|
Chris@16
|
331 while(1){
|
Chris@16
|
332 //Try to create shared memory
|
Chris@16
|
333 m_handle = shm_open(m_filename.c_str(), oflag | (O_CREAT | O_EXCL), unix_perm);
|
Chris@16
|
334 //If successful change real permissions
|
Chris@16
|
335 if(m_handle >= 0){
|
Chris@16
|
336 ::fchmod(m_handle, unix_perm);
|
Chris@16
|
337 }
|
Chris@16
|
338 //If already exists, try to open
|
Chris@16
|
339 else if(errno == EEXIST){
|
Chris@16
|
340 m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
|
Chris@16
|
341 //If open fails and errno tells the file does not exist
|
Chris@16
|
342 //(shm was removed between creation and opening tries), just retry
|
Chris@16
|
343 if(m_handle < 0 && errno == ENOENT){
|
Chris@16
|
344 continue;
|
Chris@16
|
345 }
|
Chris@16
|
346 }
|
Chris@16
|
347 //Exit retries
|
Chris@16
|
348 break;
|
Chris@16
|
349 }
|
Chris@16
|
350 }
|
Chris@16
|
351 break;
|
Chris@16
|
352 default:
|
Chris@16
|
353 {
|
Chris@16
|
354 error_info err = other_error;
|
Chris@16
|
355 throw interprocess_exception(err);
|
Chris@16
|
356 }
|
Chris@16
|
357 }
|
Chris@16
|
358
|
Chris@16
|
359 //Check for error
|
Chris@16
|
360 if(m_handle < 0){
|
Chris@16
|
361 error_info err = errno;
|
Chris@16
|
362 this->priv_close();
|
Chris@16
|
363 throw interprocess_exception(err);
|
Chris@16
|
364 }
|
Chris@16
|
365
|
Chris@16
|
366 m_filename = filename;
|
Chris@16
|
367 m_mode = mode;
|
Chris@16
|
368 return true;
|
Chris@16
|
369 }
|
Chris@16
|
370
|
Chris@16
|
371 inline bool shared_memory_object::remove(const char *filename)
|
Chris@16
|
372 {
|
Chris@16
|
373 try{
|
Chris@101
|
374 std::string filepath;
|
Chris@16
|
375 #if defined(BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
Chris@16
|
376 const bool add_leading_slash = false;
|
Chris@16
|
377 #elif defined(BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
Chris@16
|
378 const bool add_leading_slash = !shared_memory_object_detail::use_filesystem_based_posix();
|
Chris@16
|
379 #else
|
Chris@16
|
380 const bool add_leading_slash = true;
|
Chris@16
|
381 #endif
|
Chris@16
|
382 if(add_leading_slash){
|
Chris@101
|
383 ipcdetail::add_leading_slash(filename, filepath);
|
Chris@16
|
384 }
|
Chris@16
|
385 else{
|
Chris@101
|
386 ipcdetail::shared_filepath(filename, filepath);
|
Chris@16
|
387 }
|
Chris@101
|
388 return 0 == shm_unlink(filepath.c_str());
|
Chris@16
|
389 }
|
Chris@16
|
390 catch(...){
|
Chris@16
|
391 return false;
|
Chris@16
|
392 }
|
Chris@16
|
393 }
|
Chris@16
|
394
|
Chris@16
|
395 inline void shared_memory_object::truncate(offset_t length)
|
Chris@16
|
396 {
|
Chris@16
|
397 if(0 != ftruncate(m_handle, length)){
|
Chris@16
|
398 error_info err(system_error_code());
|
Chris@16
|
399 throw interprocess_exception(err);
|
Chris@16
|
400 }
|
Chris@16
|
401 }
|
Chris@16
|
402
|
Chris@16
|
403 inline void shared_memory_object::priv_close()
|
Chris@16
|
404 {
|
Chris@16
|
405 if(m_handle != -1){
|
Chris@16
|
406 ::close(m_handle);
|
Chris@16
|
407 m_handle = -1;
|
Chris@16
|
408 }
|
Chris@16
|
409 }
|
Chris@16
|
410
|
Chris@16
|
411 #endif
|
Chris@16
|
412
|
Chris@16
|
413 //!A class that stores the name of a shared memory
|
Chris@16
|
414 //!and calls shared_memory_object::remove(name) in its destructor
|
Chris@16
|
415 //!Useful to remove temporary shared memory objects in the presence
|
Chris@16
|
416 //!of exceptions
|
Chris@16
|
417 class remove_shared_memory_on_destroy
|
Chris@16
|
418 {
|
Chris@16
|
419 const char * m_name;
|
Chris@16
|
420 public:
|
Chris@16
|
421 remove_shared_memory_on_destroy(const char *name)
|
Chris@16
|
422 : m_name(name)
|
Chris@16
|
423 {}
|
Chris@16
|
424
|
Chris@16
|
425 ~remove_shared_memory_on_destroy()
|
Chris@16
|
426 { shared_memory_object::remove(m_name); }
|
Chris@16
|
427 };
|
Chris@16
|
428
|
Chris@101
|
429 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@101
|
430
|
Chris@16
|
431 } //namespace interprocess {
|
Chris@16
|
432 } //namespace boost {
|
Chris@16
|
433
|
Chris@16
|
434 #include <boost/interprocess/detail/config_end.hpp>
|
Chris@16
|
435
|
Chris@16
|
436 #endif //BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP
|