.. _program_listing_file__tmp_ws_src_ecl_core_ecl_ipc_include_ecl_ipc_shared_memory_pos.hpp: Program Listing for File shared_memory_pos.hpp ============================================== |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/ecl_core/ecl_ipc/include/ecl/ipc/shared_memory_pos.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /***************************************************************************** ** Ifdefs *****************************************************************************/ #ifndef ECL_IPC_SHARED_MEMORY_RT_HPP_ #define ECL_IPC_SHARED_MEMORY_RT_HPP_ /***************************************************************************** ** Platform Check *****************************************************************************/ #include #if defined(ECL_IS_POSIX) #include #if !defined(ECL_IS_APPLE) #include #endif #ifdef _POSIX_SHARED_MEMORY_OBJECTS #if _POSIX_SHARED_MEMORY_OBJECTS > 0 /***************************************************************************** ** Ecl Functionality Defines *****************************************************************************/ #ifndef ECL_HAS_POSIX_SHARED_MEMORY #define ECL_HAS_POSIX_SHARED_MEMORY #endif #ifndef ECL_HAS_SHARED_MEMORY #define ECL_HAS_SHARED_MEMORY #endif /***************************************************************************** ** Includes *****************************************************************************/ #include #include #include /* For shm_open() */ #include /* For O_* constants */ #include #include #include /***************************************************************************** ** Namespaces *****************************************************************************/ namespace ecl { /***************************************************************************** ** Exception Handling *****************************************************************************/ namespace ipc { #ifndef ECL_DISABLE_EXCEPTIONS // Have to be public since its called from a template (inline) function. ECL_PUBLIC ecl::StandardException openSharedSectionException(const char* loc); ECL_PUBLIC ecl::StandardException memoryMapException(const char* loc); #endif class ECL_PUBLIC SharedMemoryBase { public: void unlink(); protected: SharedMemoryBase(const std::string &name_id) : name(name_id), shared_memory_manager(false) {}; int open(); std::string name; bool shared_memory_manager; }; } // namespace ipc /***************************************************************************** ** Shared Memory *****************************************************************************/ template class ECL_PUBLIC SharedMemory : public ipc::SharedMemoryBase { public: /********************* ** C&D's **********************/ SharedMemory(const std::string& string_id); virtual ~SharedMemory(); Storage* data() { return storage; } private: SharedMemory() {} const int shared_memory_size; Storage *storage; }; /***************************************************************************** ** Implementation *****************************************************************************/ template SharedMemory::SharedMemory(const std::string& string_id ) : ipc::SharedMemoryBase(std::string("/")+string_id), shared_memory_size(sizeof(Storage)), storage(NULL) { int shm_descriptor = open(); if ( shm_descriptor == -1) { ecl_throw( ipc::openSharedSectionException(LOC) ); } /********************* * Mapping *********************/ /* * Map the shared memory into your process's address space. * * Address: 0 lets posix choose the address. * Memory Protections: PROT_READ,WRITE,EXEC,NONE. Tells the MMU what to do. Match with the shm_open parameters. * PROT_EXEC only useful if you want to run a shared library there. * Mapping Flags: Always choose MAP_SHARED for shared memory! Other options almost irrelevant. * Descriptor : shm_send_descriptor from above. * OFFSET : we should never really want to offset a chunk of memory. Just point it at the start (0). * * mmap(address,sharedMemSize,memprotections,mappingflags,descriptor,offset); */ void * shm_address; if ( (shm_address = mmap(0,shared_memory_size,PROT_READ|PROT_WRITE,MAP_SHARED,shm_descriptor,(long) 0)) == MAP_FAILED ) { shared_memory_manager = false; close(shm_descriptor); unlink(); ecl_throw( ipc::memoryMapException(LOC) ); } /* * When first created, the shared memory has 0 size. You need to inflate it before * you can use it. The second argument, the length is measured in bytes. */ if ( ftruncate(shm_descriptor,shared_memory_size) < 0 ) { shared_memory_manager = false; close(shm_descriptor); unlink(); ecl_throw(StandardException(LOC,OpenError,"Shared memory created, but inflation to the desired size failed.")); } /********************* ** Close **********************/ /* * This does not unmap the memory allocated to the block. It just closes the file * descriptor. Should do it early for tidiness if for no other reason. */ close(shm_descriptor); storage = (Storage*) shm_address; // If just allocated, initialise the shared memory structure. if ( shared_memory_manager ) { *storage = Storage(); } } template SharedMemory::~SharedMemory() { /* Might be worth putting a check on this later (i.e. < 0 is an error). */ munmap( (void*) storage,shared_memory_size); // munmap(shm_address,shared_memory_size); if ( shared_memory_manager ) { unlink(); } } } // namespace ecl #endif /* _POSIX_SHARED_MEMORY_OBJECTS > 0 */ #endif /* _POSIX_SHARED_MEMORY_OBJECTS */ #endif /* ECL_IS_POSIX */ #endif /* ECL_IPC_SHARED_MEMORY_RT_HPP_ */