shared_memory_pos.hpp
Go to the documentation of this file.
1 
10 /*****************************************************************************
11 ** Ifdefs
12 *****************************************************************************/
13 
14 #ifndef ECL_IPC_SHARED_MEMORY_RT_HPP_
15 #define ECL_IPC_SHARED_MEMORY_RT_HPP_
16 
17 /*****************************************************************************
18 ** Platform Check
19 *****************************************************************************/
20 
21 #include <ecl/config.hpp>
22 #if defined(ECL_IS_POSIX)
23 #include <unistd.h>
24 #if !defined(ECL_IS_APPLE)
25 #include <bits/posix_opt.h>
26 #endif
27 #ifdef _POSIX_SHARED_MEMORY_OBJECTS
28 #if _POSIX_SHARED_MEMORY_OBJECTS > 0
29 
30 /*****************************************************************************
31 ** Ecl Functionality Defines
32 *****************************************************************************/
33 
34 #ifndef ECL_HAS_POSIX_SHARED_MEMORY
35  #define ECL_HAS_POSIX_SHARED_MEMORY
36 #endif
37 #ifndef ECL_HAS_SHARED_MEMORY
38  #define ECL_HAS_SHARED_MEMORY
39 #endif
40 
41 /*****************************************************************************
42 ** Includes
43 *****************************************************************************/
44 
45 #include <sstream>
46 #include <string>
47 #include <sys/mman.h> /* For shm_open() */
48 #include <fcntl.h> /* For O_* constants */
51 #include <ecl/config/macros.hpp>
52 
53 /*****************************************************************************
54 ** Namespaces
55 *****************************************************************************/
56 
57 namespace ecl {
58 
59 /*****************************************************************************
60 ** Exception Handling
61 *****************************************************************************/
62 
63 namespace ipc {
64 
65 #ifndef ECL_DISABLE_EXCEPTIONS
66 
74 // Have to be public since its called from a template (inline) function.
75 ECL_PUBLIC ecl::StandardException openSharedSectionException(const char* loc);
84 ECL_PUBLIC ecl::StandardException memoryMapException(const char* loc);
85 #endif
86 
94 class ECL_PUBLIC SharedMemoryBase {
95 public:
101  void unlink();
102 
103 protected:
104  SharedMemoryBase(const std::string &name_id) :
105  name(name_id),
106  shared_memory_manager(false)
107  {};
115  int open();
116 
117  std::string name;
118  bool shared_memory_manager;
119 };
120 
121 } // namespace ipc
122 
123 /*****************************************************************************
124 ** Shared Memory
125 *****************************************************************************/
137 template <typename Storage>
138 class ECL_PUBLIC SharedMemory : public ipc::SharedMemoryBase
139 {
140 public:
141  /*********************
142  ** C&D's
143  **********************/
144  SharedMemory(const std::string& string_id);
145  virtual ~SharedMemory();
146 
147  Storage* data() { return storage; }
149 private:
150  SharedMemory() {}
151  const int shared_memory_size;
152  Storage *storage;
153 };
154 
155 /*****************************************************************************
156 ** Implementation
157 *****************************************************************************/
158 
170 template <typename Storage>
171 SharedMemory<Storage>::SharedMemory(const std::string& string_id ) :
172  ipc::SharedMemoryBase(std::string("/")+string_id),
173  shared_memory_size(sizeof(Storage)),
174  storage(NULL)
175 {
176  int shm_descriptor = open();
177  if ( shm_descriptor == -1) {
178  ecl_throw( ipc::openSharedSectionException(LOC) );
179  }
180  /*********************
181  * Mapping
182  *********************/
183  /*
184  * Map the shared memory into your process's address space.
185  *
186  * Address: 0 lets posix choose the address.
187  * Memory Protections: PROT_READ,WRITE,EXEC,NONE. Tells the MMU what to do. Match with the shm_open parameters.
188  * PROT_EXEC only useful if you want to run a shared library there.
189  * Mapping Flags: Always choose MAP_SHARED for shared memory! Other options almost irrelevant.
190  * Descriptor : shm_send_descriptor from above.
191  * OFFSET : we should never really want to offset a chunk of memory. Just point it at the start (0).
192  *
193  * mmap(address,sharedMemSize,memprotections,mappingflags,descriptor,offset);
194  */
195  void * shm_address;
196  if ( (shm_address = mmap(0,shared_memory_size,PROT_READ|PROT_WRITE,MAP_SHARED,shm_descriptor,(long) 0)) == MAP_FAILED )
197  {
198  shared_memory_manager = false;
199  close(shm_descriptor);
200  unlink();
201  ecl_throw( ipc::memoryMapException(LOC) );
202  }
203  /*
204  * When first created, the shared memory has 0 size. You need to inflate it before
205  * you can use it. The second argument, the length is measured in bytes.
206  */
207  if ( ftruncate(shm_descriptor,shared_memory_size) < 0 )
208  {
209  shared_memory_manager = false;
210  close(shm_descriptor);
211  unlink();
212  ecl_throw(StandardException(LOC,OpenError,"Shared memory created, but inflation to the desired size failed."));
213  }
214 
215  /*********************
216  ** Close
217  **********************/
218  /*
219  * This does not unmap the memory allocated to the block. It just closes the file
220  * descriptor. Should do it early for tidiness if for no other reason.
221  */
222  close(shm_descriptor);
223 
224  storage = (Storage*) shm_address;
225 
226  // If just allocated, initialise the shared memory structure.
227  if ( shared_memory_manager ) {
228  *storage = Storage();
229  }
230 }
236 template <typename Storage>
237 SharedMemory<Storage>::~SharedMemory()
238 {
239  /* Might be worth putting a check on this later (i.e. < 0 is an error). */
240  munmap( (void*) storage,shared_memory_size);
241 // munmap(shm_address,shared_memory_size);
242 
243  if ( shared_memory_manager ) {
244  unlink();
245  }
246 }
247 
248 }; // namespace ecl
249 
250 
251 #endif /* _POSIX_SHARED_MEMORY_OBJECTS > 0 */
252 #endif /* _POSIX_SHARED_MEMORY_OBJECTS */
253 #endif /* ECL_IS_POSIX */
254 
255 #endif /* ECL_IPC_SHARED_MEMORY_RT_HPP_ */
ecl::StandardException
config.hpp
standard_exception.hpp
ecl_throw
#define ecl_throw(exception)
macros.hpp
ecl
Embedded control libraries.
ECL_PUBLIC
#define ECL_PUBLIC


ecl_ipc
Author(s): Daniel Stonier
autogenerated on Wed Mar 2 2022 00:16:21