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