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 #ifndef ECL_DISABLE_EXCEPTIONS
00064
00072
00073 ECL_PUBLIC ecl::StandardException openSharedSectionException(const char* loc);
00082 ECL_PUBLIC ecl::StandardException memoryMapException(const char* loc);
00083 #endif
00084
00092 class ECL_PUBLIC SharedMemoryBase {
00093 public:
00099 void unlink();
00100
00101 protected:
00102 SharedMemoryBase(const std::string &name_id) :
00103 name(name_id),
00104 shared_memory_manager(false)
00105 {};
00113 int open();
00114
00115 std::string name;
00116 bool shared_memory_manager;
00117 };
00118
00119 }
00120
00121
00122
00123
00135 template <typename Storage>
00136 class ECL_PUBLIC SharedMemory : public ipc::SharedMemoryBase
00137 {
00138 public:
00139
00140
00141
00142 SharedMemory(const std::string& string_id) ecl_throw_decl(StandardException);
00143 virtual ~SharedMemory();
00144
00145 Storage* data() { return storage; }
00147 private:
00148 SharedMemory() {}
00149 const int shared_memory_size;
00150 Storage *storage;
00151 };
00152
00153
00154
00155
00156
00168 template <typename Storage>
00169 SharedMemory<Storage>::SharedMemory(const std::string& string_id ) ecl_throw_decl(StandardException) :
00170 ipc::SharedMemoryBase(std::string("/")+string_id),
00171 shared_memory_size(sizeof(Storage)),
00172 storage(NULL)
00173 {
00174 int shm_descriptor = open();
00175 if ( shm_descriptor == -1) {
00176 ecl_throw( ipc::openSharedSectionException(LOC) );
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 void * shm_address;
00194 if ( (shm_address = mmap(0,shared_memory_size,PROT_READ|PROT_WRITE,MAP_SHARED,shm_descriptor,(long) 0)) == MAP_FAILED )
00195 {
00196 shared_memory_manager = false;
00197 close(shm_descriptor);
00198 unlink();
00199 ecl_throw( ipc::memoryMapException(LOC) );
00200 }
00201
00202
00203
00204
00205 if ( ftruncate(shm_descriptor,shared_memory_size) < 0 )
00206 {
00207 shared_memory_manager = false;
00208 close(shm_descriptor);
00209 unlink();
00210 ecl_throw(StandardException(LOC,OpenError,"Shared memory created, but inflation to the desired size failed."));
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 close(shm_descriptor);
00221
00222 storage = (Storage*) shm_address;
00223
00224
00225 if ( shared_memory_manager ) {
00226 *storage = Storage();
00227 }
00228 }
00234 template <typename Storage>
00235 SharedMemory<Storage>::~SharedMemory()
00236 {
00237
00238 munmap( (void*) storage,shared_memory_size);
00239
00240
00241 if ( shared_memory_manager ) {
00242 unlink();
00243 }
00244 }
00245
00246 };
00247
00248
00249 #endif
00250 #endif
00251 #endif
00252
00253 #endif