Go to the documentation of this file.00001 
00010 
00011 
00012 
00013 
00014 #ifndef ECL_IPC_SHARED_MEMORY_RT_HPP_
00015 #define ECL_IPC_SHARED_MEMORY_RT_HPP_
00016 
00017 
00018 
00019 
00020 
00021 #include <ecl/config.hpp>
00022 #if defined(ECL_IS_POSIX)
00023 #include <unistd.h>
00024 #include <bits/posix_opt.h>
00025 #ifdef _POSIX_SHARED_MEMORY_OBJECTS
00026 #if _POSIX_SHARED_MEMORY_OBJECTS > 0
00027 
00028 
00029 
00030 
00031 
00032 #ifndef ECL_HAS_POSIX_SHARED_MEMORY
00033   #define ECL_HAS_POSIX_SHARED_MEMORY
00034 #endif
00035 #ifndef ECL_HAS_SHARED_MEMORY
00036   #define ECL_HAS_SHARED_MEMORY
00037 #endif
00038 
00039 
00040 
00041 
00042 
00043 #include <sstream>
00044 #include <string>
00045 #include <sys/mman.h>        
00046 #include <fcntl.h>           
00047 #include <ecl/exceptions/macros.hpp>
00048 #include <ecl/exceptions/standard_exception.hpp>
00049 #include <ecl/config/macros.hpp>
00050 
00051 
00052 
00053 
00054 
00055 namespace ecl {
00056 
00057 
00058 
00059 
00060 
00061 namespace ipc {
00062 
00063 #ifdef ECL_HAS_EXCEPTIONS
00064 
00073 
00074 ECL_PUBLIC ecl::StandardException openSharedSectionException(const char* loc);
00083 ECL_PUBLIC ecl::StandardException memoryMapException(const char* loc);
00084 
00085 
00086 #endif 
00087 
00095 class ECL_PUBLIC SharedMemoryBase {
00096 public:
00102         void unlink();
00103 
00104 protected:
00105         SharedMemoryBase(const std::string &name_id) :
00106                 name(name_id),
00107                 shared_memory_manager(false)
00108         {};
00116         int open();
00117 
00118         std::string name;
00119         bool shared_memory_manager;
00120 };
00121 
00122 } 
00123 
00124 
00125 
00126 
00138 template <typename Storage>
00139 class ECL_PUBLIC SharedMemory : public ipc::SharedMemoryBase
00140 {
00141 public:
00142         
00143 
00144 
00145         SharedMemory(const std::string& string_id) ecl_throw_decl(StandardException);
00146         virtual ~SharedMemory();
00147 
00148         Storage* data() { return storage; }         
00150 private:
00151         SharedMemory() {} 
00152         const int shared_memory_size;
00153         Storage *storage;
00154 };
00155 
00156 
00157 
00158 
00159 
00171 template <typename Storage>
00172 SharedMemory<Storage>::SharedMemory(const std::string& string_id ) ecl_throw_decl(StandardException)  :
00173         ipc::SharedMemoryBase(std::string("/")+string_id),
00174         shared_memory_size(sizeof(Storage)),
00175         storage(NULL)
00176 {
00177         int shm_descriptor = open();
00178     if ( shm_descriptor == -1) {
00179         ecl_throw( ipc::openSharedSectionException(LOC) );
00180     }
00181     
00182 
00183 
00184     
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196     void * shm_address;
00197     if ( (shm_address = mmap(0,shared_memory_size,PROT_READ|PROT_WRITE,MAP_SHARED,shm_descriptor,(long) 0)) == MAP_FAILED )
00198     {
00199         shared_memory_manager = false;
00200         close(shm_descriptor);
00201         unlink();
00202         ecl_throw( ipc::memoryMapException(LOC) );
00203     }
00204     
00205 
00206 
00207 
00208     if ( ftruncate(shm_descriptor,shared_memory_size) < 0 )
00209     {
00210         shared_memory_manager = false;
00211         close(shm_descriptor);
00212         unlink();
00213         ecl_throw(StandardException(LOC,OpenError,"Shared memory created, but inflation to the desired size failed."));
00214     }
00215 
00216     
00217 
00218 
00219     
00220 
00221 
00222 
00223     close(shm_descriptor);
00224 
00225     storage = (Storage*) shm_address;
00226 
00227     
00228     if ( shared_memory_manager ) {
00229         *storage = Storage();
00230     }
00231 }
00237 template <typename Storage>
00238 SharedMemory<Storage>::~SharedMemory()
00239 {
00240     
00241     munmap( (void*) storage,shared_memory_size);
00242 
00243 
00244     if ( shared_memory_manager ) {
00245         unlink();
00246     }
00247 }
00248 
00249 }; 
00250 
00251 
00252 #endif 
00253 #endif 
00254 #endif 
00255 
00256 #endif