Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org/libs/interprocess for documentation. Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #ifndef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP Chris@16: #define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP Chris@16: Chris@101: #ifndef BOOST_CONFIG_HPP Chris@101: # include Chris@101: #endif Chris@101: # Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@101: # pragma once Chris@101: #endif Chris@101: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if !defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS) Chris@16: #error "This header can't be used in operating systems without XSI (System V) shared memory support" Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@101: // move Chris@101: #include Chris@101: // other boost Chris@101: #include Chris@101: // std Chris@101: #include Chris@101: // OS Chris@16: #include Chris@101: Chris@16: Chris@16: //!\file Chris@16: //!Describes a class representing a native xsi shared memory. Chris@16: Chris@16: namespace boost { Chris@16: namespace interprocess { Chris@16: Chris@16: //!A class that wraps XSI (System V) shared memory. Chris@16: //!Unlike shared_memory_object, xsi_shared_memory needs a valid Chris@16: //!xsi_key to identify a shared memory object. Chris@16: //! Chris@16: //!Warning: XSI shared memory and interprocess portable Chris@16: //!shared memory (boost::interprocess::shared_memory_object) Chris@16: //!can't communicate between them. Chris@16: class xsi_shared_memory Chris@16: { Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: //Non-copyable and non-assignable Chris@16: BOOST_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory) Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: public: Chris@16: //!Default constructor. Chris@16: //!Represents an empty xsi_shared_memory. Chris@16: xsi_shared_memory(); Chris@16: Chris@16: //!Initializes *this with a shmid previously obtained (possibly from another process) Chris@16: //!This lower-level initializer allows shared memory mapping without having a key. Chris@16: xsi_shared_memory(open_only_t, int shmid) Chris@16: : m_shmid (shmid) Chris@16: {} Chris@16: Chris@16: //!Creates a new XSI shared memory from 'key', with size "size" and permissions "perm". Chris@16: //!If the shared memory previously exists, throws an error. Chris@16: xsi_shared_memory(create_only_t, const xsi_key &key, std::size_t size, const permissions& perm = permissions()) Chris@16: { this->priv_open_or_create(ipcdetail::DoCreate, key, perm, size); } Chris@16: Chris@16: //!Opens an existing shared memory with identifier 'key' or creates a new XSI shared memory from Chris@16: //!identifier 'key', with size "size" and permissions "perm". Chris@16: xsi_shared_memory(open_or_create_t, const xsi_key &key, std::size_t size, const permissions& perm = permissions()) Chris@16: { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, key, perm, size); } Chris@16: Chris@16: //!Tries to open a XSI shared memory with identifier 'key' Chris@16: //!If the shared memory does not previously exist, it throws an error. Chris@16: xsi_shared_memory(open_only_t, const xsi_key &key) Chris@16: { this->priv_open_or_create(ipcdetail::DoOpen, key, permissions(), 0); } Chris@16: Chris@16: //!Moves the ownership of "moved"'s shared memory object to *this. Chris@16: //!After the call, "moved" does not represent any shared memory object. Chris@16: //!Does not throw Chris@16: xsi_shared_memory(BOOST_RV_REF(xsi_shared_memory) moved) Chris@16: : m_shmid(-1) Chris@16: { this->swap(moved); } Chris@16: Chris@16: //!Moves the ownership of "moved"'s shared memory to *this. Chris@16: //!After the call, "moved" does not represent any shared memory. Chris@16: //!Does not throw Chris@16: xsi_shared_memory &operator=(BOOST_RV_REF(xsi_shared_memory) moved) Chris@16: { Chris@16: xsi_shared_memory tmp(boost::move(moved)); Chris@16: this->swap(tmp); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: //!Swaps two xsi_shared_memorys. Does not throw Chris@16: void swap(xsi_shared_memory &other); Chris@16: Chris@16: //!Destroys *this. The shared memory won't be destroyed, just Chris@16: //!this connection to it. Use remove() to destroy the shared memory. Chris@16: ~xsi_shared_memory(); Chris@16: Chris@16: //!Returns the shared memory ID that Chris@16: //!identifies the shared memory Chris@16: int get_shmid() const; Chris@16: Chris@16: //!Returns the mapping handle. Chris@16: //!Never throws Chris@16: mapping_handle_t get_mapping_handle() const; Chris@16: Chris@16: //!Erases the XSI shared memory object identified by shmid Chris@16: //!from the system. Chris@16: //!Returns false on error. Never throws Chris@16: static bool remove(int shmid); Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: Chris@16: //!Closes a previously opened file mapping. Never throws. Chris@16: bool priv_open_or_create( ipcdetail::create_enum_t type Chris@16: , const xsi_key &key Chris@16: , const permissions& perm Chris@16: , std::size_t size); Chris@16: int m_shmid; Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: }; Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: Chris@16: inline xsi_shared_memory::xsi_shared_memory() Chris@16: : m_shmid(-1) Chris@16: {} Chris@16: Chris@16: inline xsi_shared_memory::~xsi_shared_memory() Chris@16: {} Chris@16: Chris@16: inline int xsi_shared_memory::get_shmid() const Chris@16: { return m_shmid; } Chris@16: Chris@16: inline void xsi_shared_memory::swap(xsi_shared_memory &other) Chris@16: { Chris@101: (simple_swap)(m_shmid, other.m_shmid); Chris@16: } Chris@16: Chris@16: inline mapping_handle_t xsi_shared_memory::get_mapping_handle() const Chris@16: { mapping_handle_t mhnd = { m_shmid, true}; return mhnd; } Chris@16: Chris@16: inline bool xsi_shared_memory::priv_open_or_create Chris@16: (ipcdetail::create_enum_t type, const xsi_key &key, const permissions& permissions, std::size_t size) Chris@16: { Chris@16: int perm = permissions.get_permissions(); Chris@16: perm &= 0x01FF; Chris@16: int shmflg = perm; Chris@16: Chris@16: switch(type){ Chris@16: case ipcdetail::DoOpen: Chris@16: shmflg |= 0; Chris@16: break; Chris@16: case ipcdetail::DoCreate: Chris@16: shmflg |= IPC_CREAT | IPC_EXCL; Chris@16: break; Chris@16: case ipcdetail::DoOpenOrCreate: Chris@16: shmflg |= IPC_CREAT; Chris@16: break; Chris@16: default: Chris@16: { Chris@16: error_info err = other_error; Chris@16: throw interprocess_exception(err); Chris@16: } Chris@16: } Chris@16: Chris@16: int ret = ::shmget(key.get_key(), size, shmflg); Chris@16: int shmid = ret; Chris@16: if((type == ipcdetail::DoOpen) && (-1 != ret)){ Chris@16: //Now get the size Chris@16: ::shmid_ds xsi_ds; Chris@16: ret = ::shmctl(ret, IPC_STAT, &xsi_ds); Chris@16: size = xsi_ds.shm_segsz; Chris@16: } Chris@16: if(-1 == ret){ Chris@16: error_info err = system_error_code(); Chris@16: throw interprocess_exception(err); Chris@16: } Chris@16: Chris@16: m_shmid = shmid; Chris@16: return true; Chris@16: } Chris@16: Chris@16: inline bool xsi_shared_memory::remove(int shmid) Chris@16: { return -1 != ::shmctl(shmid, IPC_RMID, 0); } Chris@16: Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: } //namespace interprocess { Chris@16: } //namespace boost { Chris@16: Chris@16: #include Chris@16: Chris@16: #endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP