shared_memory_pos.hpp
Go to the documentation of this file.
00001 
00010 /*****************************************************************************
00011 ** Ifdefs
00012 *****************************************************************************/
00013 
00014 #ifndef ECL_IPC_SHARED_MEMORY_RT_HPP_
00015 #define ECL_IPC_SHARED_MEMORY_RT_HPP_
00016 
00017 /*****************************************************************************
00018 ** Platform Check
00019 *****************************************************************************/
00020 
00021 #include <ecl/config.hpp>
00022 #if defined(ECL_IS_POSIX)
00023 #include <unistd.h>
00024 #if !defined(ECL_IS_APPLE)
00025 #include <bits/posix_opt.h>
00026 #endif
00027 #ifdef _POSIX_SHARED_MEMORY_OBJECTS
00028 #if _POSIX_SHARED_MEMORY_OBJECTS > 0
00029 
00030 /*****************************************************************************
00031 ** Ecl Functionality Defines
00032 *****************************************************************************/
00033 
00034 #ifndef ECL_HAS_POSIX_SHARED_MEMORY
00035   #define ECL_HAS_POSIX_SHARED_MEMORY
00036 #endif
00037 #ifndef ECL_HAS_SHARED_MEMORY
00038   #define ECL_HAS_SHARED_MEMORY
00039 #endif
00040 
00041 /*****************************************************************************
00042 ** Includes
00043 *****************************************************************************/
00044 
00045 #include <sstream>
00046 #include <string>
00047 #include <sys/mman.h>        /* For shm_open() */
00048 #include <fcntl.h>           /* For O_* constants */
00049 #include <ecl/exceptions/macros.hpp>
00050 #include <ecl/exceptions/standard_exception.hpp>
00051 #include <ecl/config/macros.hpp>
00052 
00053 /*****************************************************************************
00054 ** Namespaces
00055 *****************************************************************************/
00056 
00057 namespace ecl {
00058 
00059 /*****************************************************************************
00060 ** Exception Handling
00061 *****************************************************************************/
00062 
00063 namespace ipc {
00064 
00065 #ifndef ECL_DISABLE_EXCEPTIONS
00066 
00074 // Have to be public since its called from a template (inline) function.
00075 ECL_PUBLIC ecl::StandardException openSharedSectionException(const char* loc);
00084 ECL_PUBLIC ecl::StandardException memoryMapException(const char* loc);
00085 #endif
00086 
00094 class ECL_PUBLIC SharedMemoryBase {
00095 public:
00101         void unlink();
00102 
00103 protected:
00104         SharedMemoryBase(const std::string &name_id) :
00105                 name(name_id),
00106                 shared_memory_manager(false)
00107         {};
00115         int open();
00116 
00117         std::string name;
00118         bool shared_memory_manager;
00119 };
00120 
00121 } // namespace ipc
00122 
00123 /*****************************************************************************
00124 ** Shared Memory
00125 *****************************************************************************/
00137 template <typename Storage>
00138 class ECL_PUBLIC SharedMemory : public ipc::SharedMemoryBase
00139 {
00140 public:
00141         /*********************
00142         ** C&D's
00143         **********************/
00144         SharedMemory(const std::string& string_id) ecl_throw_decl(StandardException);
00145         virtual ~SharedMemory();
00146 
00147         Storage* data() { return storage; }         
00149 private:
00150         SharedMemory() {} 
00151         const int shared_memory_size;
00152         Storage *storage;
00153 };
00154 
00155 /*****************************************************************************
00156 ** Implementation
00157 *****************************************************************************/
00158 
00170 template <typename Storage>
00171 SharedMemory<Storage>::SharedMemory(const std::string& string_id ) ecl_throw_decl(StandardException)  :
00172         ipc::SharedMemoryBase(std::string("/")+string_id),
00173         shared_memory_size(sizeof(Storage)),
00174         storage(NULL)
00175 {
00176         int shm_descriptor = open();
00177     if ( shm_descriptor == -1) {
00178         ecl_throw( ipc::openSharedSectionException(LOC) );
00179     }
00180     /*********************
00181      * Mapping
00182      *********************/
00183     /*
00184      * Map the shared memory into your process's address space.
00185      *
00186      * Address: 0 lets posix choose the address.
00187      * Memory Protections: PROT_READ,WRITE,EXEC,NONE. Tells the MMU what to do. Match with the shm_open parameters.
00188      *                     PROT_EXEC only useful if you want to run a shared library there.
00189      * Mapping Flags: Always choose MAP_SHARED for shared memory! Other options almost irrelevant.
00190      * Descriptor : shm_send_descriptor from above.
00191      * OFFSET : we should never really want to offset a chunk of memory. Just point it at the start (0).
00192      *
00193      * mmap(address,sharedMemSize,memprotections,mappingflags,descriptor,offset);
00194      */
00195     void * shm_address;
00196     if ( (shm_address = mmap(0,shared_memory_size,PROT_READ|PROT_WRITE,MAP_SHARED,shm_descriptor,(long) 0)) == MAP_FAILED )
00197     {
00198         shared_memory_manager = false;
00199         close(shm_descriptor);
00200         unlink();
00201         ecl_throw( ipc::memoryMapException(LOC) );
00202     }
00203     /*
00204      * When first created, the shared memory has 0 size. You need to inflate it before
00205      * you can use it. The second argument, the length is measured in bytes.
00206      */
00207     if ( ftruncate(shm_descriptor,shared_memory_size) < 0 )
00208     {
00209         shared_memory_manager = false;
00210         close(shm_descriptor);
00211         unlink();
00212         ecl_throw(StandardException(LOC,OpenError,"Shared memory created, but inflation to the desired size failed."));
00213     }
00214 
00215     /*********************
00216     ** Close
00217     **********************/
00218     /*
00219      * This does not unmap the memory allocated to the block. It just closes the file
00220      * descriptor. Should do it early for tidiness if for no other reason.
00221      */
00222     close(shm_descriptor);
00223 
00224     storage = (Storage*) shm_address;
00225 
00226     // If just allocated, initialise the shared memory structure.
00227     if ( shared_memory_manager ) {
00228         *storage = Storage();
00229     }
00230 }
00236 template <typename Storage>
00237 SharedMemory<Storage>::~SharedMemory()
00238 {
00239     /* Might be worth putting a check on this later (i.e. < 0 is an error). */
00240     munmap( (void*) storage,shared_memory_size);
00241 //    munmap(shm_address,shared_memory_size);
00242 
00243     if ( shared_memory_manager ) {
00244         unlink();
00245     }
00246 }
00247 
00248 }; // namespace ecl
00249 
00250 
00251 #endif /* _POSIX_SHARED_MEMORY_OBJECTS > 0 */
00252 #endif /* _POSIX_SHARED_MEMORY_OBJECTS */
00253 #endif /* ECL_IS_POSIX */
00254 
00255 #endif /* ECL_IPC_SHARED_MEMORY_RT_HPP_ */


ecl_ipc
Author(s): Daniel Stonier
autogenerated on Mon Jul 3 2017 02:21:22