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 #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
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
00043
00044
00045 #include <sstream>
00046 #include <string>
00047 #include <sys/mman.h>
00048 #include <fcntl.h>
00049 #include <ecl/exceptions/macros.hpp>
00050 #include <ecl/exceptions/standard_exception.hpp>
00051 #include <ecl/config/macros.hpp>
00052
00053
00054
00055
00056
00057 namespace ecl {
00058
00059
00060
00061
00062
00063 namespace ipc {
00064
00065 #ifndef ECL_DISABLE_EXCEPTIONS
00066
00074
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 }
00122
00123
00124
00125
00137 template <typename Storage>
00138 class ECL_PUBLIC SharedMemory : public ipc::SharedMemoryBase
00139 {
00140 public:
00141
00142
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
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
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
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
00205
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
00217
00218
00219
00220
00221
00222 close(shm_descriptor);
00223
00224 storage = (Storage*) shm_address;
00225
00226
00227 if ( shared_memory_manager ) {
00228 *storage = Storage();
00229 }
00230 }
00236 template <typename Storage>
00237 SharedMemory<Storage>::~SharedMemory()
00238 {
00239
00240 munmap( (void*) storage,shared_memory_size);
00241
00242
00243 if ( shared_memory_manager ) {
00244 unlink();
00245 }
00246 }
00247
00248 };
00249
00250
00251 #endif
00252 #endif
00253 #endif
00254
00255 #endif