1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2008. 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)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP
12 #define BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP
14 #include <boost/interprocess/detail/config_begin.hpp>
15 #include <boost/interprocess/detail/workaround.hpp>
16 #include <boost/interprocess/creation_tags.hpp>
17 #include <boost/interprocess/exceptions.hpp>
18 #include <boost/interprocess/detail/move.hpp>
19 #include <boost/interprocess/interprocess_fwd.hpp>
20 #include <boost/interprocess/exceptions.hpp>
21 #include <boost/interprocess/detail/os_file_functions.hpp>
22 #include <boost/interprocess/detail/tmp_dir_helpers.hpp>
27 #if defined(BOOST_INTERPROCESS_SYSTEM_V_SHARED_MEMORY_OBJECTS)
28 # include <sys/shm.h> //System V shared memory...
29 #elif defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
30 # include <fcntl.h> //O_CREAT, O_*...
31 # include <sys/mman.h> //shm_xxx
32 # include <unistd.h> //ftruncate, close
33 # include <sys/stat.h> //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
39 //!Describes a shared memory object management class.
42 namespace interprocess
{
44 //!A class that wraps a shared memory mapping that can be used to
45 //!create mapped regions from the mapped files
46 class shared_memory_object
49 //Non-copyable and non-assignable
50 shared_memory_object(shared_memory_object
&);
51 shared_memory_object
&operator=(shared_memory_object
&);
55 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(shared_memory_object
)
57 //!Default constructor. Represents an empty shared_memory_object.
58 shared_memory_object();
60 //!Creates a shared memory object with name "name" and mode "mode", with the access mode "mode"
61 //!If the file previously exists, throws an error.*/
62 shared_memory_object(create_only_t
, const char *name
, mode_t mode
)
63 { this->priv_open_or_create(detail::DoCreate
, name
, mode
); }
65 //!Tries to create a shared memory object with name "name" and mode "mode", with the
66 //!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
67 //!Otherwise throws an error.
68 shared_memory_object(open_or_create_t
, const char *name
, mode_t mode
)
69 { this->priv_open_or_create(detail::DoOpenOrCreate
, name
, mode
); }
71 //!Tries to open a shared memory object with name "name", with the access mode "mode".
72 //!If the file does not previously exist, it throws an error.
73 shared_memory_object(open_only_t
, const char *name
, mode_t mode
)
74 { this->priv_open_or_create(detail::DoOpen
, name
, mode
); }
76 //!Moves the ownership of "moved"'s shared memory object to *this.
77 //!After the call, "moved" does not represent any shared memory object.
79 shared_memory_object(BOOST_INTERPROCESS_RV_REF(shared_memory_object
) moved
)
80 : m_handle(file_handle_t(detail::invalid_file()))
81 { this->swap(moved
); }
83 //!Moves the ownership of "moved"'s shared memory to *this.
84 //!After the call, "moved" does not represent any shared memory.
86 shared_memory_object
&operator=(BOOST_INTERPROCESS_RV_REF(shared_memory_object
) moved
)
88 shared_memory_object
tmp(boost::interprocess::move(moved
));
93 //!Swaps the shared_memory_objects. Does not throw
94 void swap(shared_memory_object
&moved
);
96 //!Erases a shared memory object from the system.
97 //!Returns false on error. Never throws
98 static bool remove(const char *name
);
100 //!Sets the size of the shared memory mapping
101 void truncate(offset_t length
);
103 //!Destroys *this and indicates that the calling process is finished using
104 //!the resource. All mapped regions are still
105 //!valid after destruction. The destructor function will deallocate
106 //!any system resources allocated by the system for use by this process for
107 //!this resource. The resource can still be opened again calling
108 //!the open constructor overload. To erase the resource from the system
110 ~shared_memory_object();
112 //!Returns the name of the file.
113 const char *get_name() const;
115 //!Returns the name of the file
116 //!used in the constructor
117 bool get_size(offset_t
&size
) const;
119 //!Returns access mode
120 mode_t
get_mode() const;
122 //!Returns mapping handle. Never throws.
123 mapping_handle_t
get_mapping_handle() const;
128 //!Closes a previously opened file mapping. Never throws.
131 //!Closes a previously opened file mapping. Never throws.
132 bool priv_open_or_create(detail::create_enum_t type
, const char *filename
, mode_t mode
);
134 file_handle_t m_handle
;
136 std::string m_filename
;
142 inline shared_memory_object::shared_memory_object()
143 : m_handle(file_handle_t(detail::invalid_file()))
146 inline shared_memory_object::~shared_memory_object()
147 { this->priv_close(); }
150 inline const char *shared_memory_object::get_name() const
151 { return m_filename
.c_str(); }
153 inline bool shared_memory_object::get_size(offset_t
&size
) const
154 { return detail::get_file_size((file_handle_t
)m_handle
, size
); }
156 inline void shared_memory_object::swap(shared_memory_object
&other
)
158 std::swap(m_handle
, other
.m_handle
);
159 std::swap(m_mode
, other
.m_mode
);
160 m_filename
.swap(other
.m_filename
);
163 inline mapping_handle_t
shared_memory_object::get_mapping_handle() const
165 return detail::mapping_handle_from_file_handle(m_handle
);
168 inline mode_t
shared_memory_object::get_mode() const
171 #if !defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
173 inline bool shared_memory_object::priv_open_or_create
174 (detail::create_enum_t type
, const char *filename
, mode_t mode
)
176 m_filename
= filename
;
178 detail::create_tmp_dir_and_get_filename(filename
, shmfile
);
181 if (mode
!= read_write
&& mode
!= read_only
){
182 error_info err
= other_error
;
183 throw interprocess_exception(err
);
188 m_handle
= detail::open_existing_file(shmfile
.c_str(), mode
, true);
190 case detail::DoCreate
:
191 m_handle
= detail::create_new_file(shmfile
.c_str(), mode
, true);
193 case detail::DoOpenOrCreate
:
194 m_handle
= detail::create_or_open_file(shmfile
.c_str(), mode
, true);
198 error_info err
= other_error
;
199 throw interprocess_exception(err
);
204 if(m_handle
== detail::invalid_file()){
205 error_info err
= system_error_code();
207 throw interprocess_exception(err
);
214 inline bool shared_memory_object::remove(const char *filename
)
217 //Make sure a temporary path is created for shared memory
219 detail::tmp_filename(filename
, shmfile
);
220 return detail::delete_file(shmfile
.c_str()) == 0;
227 inline void shared_memory_object::truncate(offset_t length
)
229 if(!detail::truncate_file(m_handle
, length
)){
230 error_info err
= system_error_code();
231 throw interprocess_exception(err
);
235 inline void shared_memory_object::priv_close()
237 if(m_handle
!= detail::invalid_file()){
238 detail::close_file(m_handle
);
239 m_handle
= detail::invalid_file();
243 #else //!defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
245 inline bool shared_memory_object::priv_open_or_create
246 (detail::create_enum_t type
,
247 const char *filename
,
250 #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
251 detail::add_leading_slash(filename
, m_filename
);
253 detail::create_tmp_dir_and_get_filename(filename
, m_filename
);
258 if(mode
== read_only
){
261 else if(mode
== read_write
){
265 error_info
err(mode_error
);
266 throw interprocess_exception(err
);
273 case detail::DoCreate
:
274 oflag
|= (O_CREAT
| O_EXCL
);
276 case detail::DoOpenOrCreate
:
281 error_info err
= other_error
;
282 throw interprocess_exception(err
);
286 //Open file using POSIX API
287 m_handle
= shm_open(m_filename
.c_str(), oflag
, S_IRWXO
| S_IRWXG
| S_IRWXU
);
291 error_info err
= errno
;
293 throw interprocess_exception(err
);
296 m_filename
= filename
;
301 inline bool shared_memory_object::remove(const char *filename
)
304 std::string file_str
;
305 #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
306 detail::add_leading_slash(filename
, file_str
);
308 detail::tmp_filename(filename
, file_str
);
310 return 0 != shm_unlink(file_str
.c_str());
317 inline void shared_memory_object::truncate(offset_t length
)
319 if(0 != ftruncate(m_handle
, length
)){
320 error_info
err(system_error_code());
321 throw interprocess_exception(err
);
325 inline void shared_memory_object::priv_close()
337 //!A class that stores the name of a shared memory
338 //!and calls shared_memory_object::remove(name) in its destructor
339 //!Useful to remove temporary shared memory objects in the presence
341 class remove_shared_memory_on_destroy
345 remove_shared_memory_on_destroy(const char *name
)
349 ~remove_shared_memory_on_destroy()
350 { shared_memory_object::remove(m_name
); }
353 } //namespace interprocess {
354 } //namespace boost {
356 #include <boost/interprocess/detail/config_end.hpp>
358 #endif //BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP