File indexing completed on 2025-01-18 09:38:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP
0012 #define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024
0025 #if !defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
0026 #error "This header can't be used in operating systems without XSI (System V) shared memory support"
0027 #endif
0028
0029 #include <boost/interprocess/creation_tags.hpp>
0030 #include <boost/interprocess/exceptions.hpp>
0031 #include <boost/interprocess/detail/utilities.hpp>
0032
0033 #include <boost/interprocess/detail/os_file_functions.hpp>
0034 #include <boost/interprocess/interprocess_fwd.hpp>
0035 #include <boost/interprocess/exceptions.hpp>
0036 #include <boost/interprocess/xsi_key.hpp>
0037 #include <boost/interprocess/permissions.hpp>
0038 #include <boost/interprocess/detail/simple_swap.hpp>
0039
0040 #include <boost/move/utility_core.hpp>
0041
0042 #include <boost/cstdint.hpp>
0043
0044 #include <cstddef>
0045
0046 #include <sys/shm.h>
0047
0048
0049
0050
0051
0052 namespace boost {
0053 namespace interprocess {
0054
0055
0056
0057
0058
0059
0060
0061
0062 class xsi_shared_memory
0063 {
0064 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0065
0066 BOOST_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory)
0067 #endif
0068
0069 public:
0070
0071
0072 xsi_shared_memory() BOOST_NOEXCEPT;
0073
0074
0075
0076 xsi_shared_memory(open_only_t, int shmid)
0077 : m_shmid (shmid)
0078 {}
0079
0080
0081
0082 xsi_shared_memory(create_only_t, const xsi_key &key, std::size_t size, const permissions& perm = permissions())
0083 { this->priv_open_or_create(ipcdetail::DoCreate, key, perm, size); }
0084
0085
0086
0087 xsi_shared_memory(open_or_create_t, const xsi_key &key, std::size_t size, const permissions& perm = permissions())
0088 { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, key, perm, size); }
0089
0090
0091
0092 xsi_shared_memory(open_only_t, const xsi_key &key)
0093 { this->priv_open_or_create(ipcdetail::DoOpen, key, permissions(), 0); }
0094
0095
0096
0097
0098 xsi_shared_memory(BOOST_RV_REF(xsi_shared_memory) moved) BOOST_NOEXCEPT
0099 : m_shmid(-1)
0100 { this->swap(moved); }
0101
0102
0103
0104
0105 xsi_shared_memory &operator=(BOOST_RV_REF(xsi_shared_memory) moved) BOOST_NOEXCEPT
0106 {
0107 xsi_shared_memory tmp(boost::move(moved));
0108 this->swap(tmp);
0109 return *this;
0110 }
0111
0112
0113 void swap(xsi_shared_memory &other) BOOST_NOEXCEPT;
0114
0115
0116
0117 ~xsi_shared_memory();
0118
0119
0120
0121 int get_shmid() const BOOST_NOEXCEPT;
0122
0123
0124
0125 mapping_handle_t get_mapping_handle() const BOOST_NOEXCEPT;
0126
0127
0128
0129
0130 static bool remove(int shmid);
0131
0132 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0133 private:
0134
0135
0136 bool priv_open_or_create( ipcdetail::create_enum_t type
0137 , const xsi_key &key
0138 , const permissions& perm
0139 , std::size_t size);
0140 int m_shmid;
0141 #endif
0142 };
0143
0144 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0145
0146 inline xsi_shared_memory::xsi_shared_memory() BOOST_NOEXCEPT
0147 : m_shmid(-1)
0148 {}
0149
0150 inline xsi_shared_memory::~xsi_shared_memory()
0151 {}
0152
0153 inline int xsi_shared_memory::get_shmid() const BOOST_NOEXCEPT
0154 { return m_shmid; }
0155
0156 inline void xsi_shared_memory::swap(xsi_shared_memory &other) BOOST_NOEXCEPT
0157 {
0158 (simple_swap)(m_shmid, other.m_shmid);
0159 }
0160
0161 inline mapping_handle_t xsi_shared_memory::get_mapping_handle() const BOOST_NOEXCEPT
0162 { mapping_handle_t mhnd = { m_shmid, true}; return mhnd; }
0163
0164 inline bool xsi_shared_memory::priv_open_or_create
0165 (ipcdetail::create_enum_t type, const xsi_key &key, const permissions& permissions, std::size_t size)
0166 {
0167 int perm = (int)permissions.get_permissions();
0168 perm &= 0x01FF;
0169 int shmflg = perm;
0170
0171 switch(type){
0172 case ipcdetail::DoOpen:
0173 shmflg |= 0;
0174 break;
0175 case ipcdetail::DoCreate:
0176 shmflg |= IPC_CREAT | IPC_EXCL;
0177 break;
0178 case ipcdetail::DoOpenOrCreate:
0179 shmflg |= IPC_CREAT;
0180 break;
0181 default:
0182 {
0183 error_info err = other_error;
0184 throw interprocess_exception(err);
0185 }
0186 }
0187
0188 int ret = ::shmget(key.get_key(), size, shmflg);
0189 int shmid = ret;
0190 if((type == ipcdetail::DoOpen) && (-1 != ret)){
0191
0192 ::shmid_ds xsi_ds;
0193 ret = ::shmctl(ret, IPC_STAT, &xsi_ds);
0194 size = xsi_ds.shm_segsz;
0195 }
0196 if(-1 == ret){
0197 error_info err = system_error_code();
0198 throw interprocess_exception(err);
0199 }
0200
0201 m_shmid = shmid;
0202 return true;
0203 }
0204
0205 inline bool xsi_shared_memory::remove(int shmid)
0206 { return -1 != ::shmctl(shmid, IPC_RMID, 0); }
0207
0208 #endif
0209
0210 }
0211 }
0212
0213 #include <boost/interprocess/detail/config_end.hpp>
0214
0215 #endif