mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
Added XSI shared memory
[SVN r67449]
This commit is contained in:
@@ -35,4 +35,6 @@ using boost::container::ordered_unique_range;
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
/// @endcond
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_CONTAINERS_FWD_HPP
|
||||
|
||||
@@ -53,6 +53,7 @@ class file_wrapper
|
||||
//!After the call, "moved" does not represent any file.
|
||||
//!Does not throw
|
||||
file_wrapper(BOOST_INTERPROCESS_RV_REF(file_wrapper) moved)
|
||||
: m_handle(file_handle_t(detail::invalid_file()))
|
||||
{ this->swap(moved); }
|
||||
|
||||
//!Moves the ownership of "moved"'s file to *this.
|
||||
|
||||
@@ -30,16 +30,66 @@ namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
namespace detail{ class interprocess_tester; }
|
||||
|
||||
|
||||
template<class DeviceAbstraction>
|
||||
struct managed_open_or_create_impl_device_id_t
|
||||
{
|
||||
typedef const char *type;
|
||||
};
|
||||
|
||||
#ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
|
||||
|
||||
class xsi_shared_memory_file_wrapper;
|
||||
class xsi_key;
|
||||
|
||||
template<>
|
||||
struct managed_open_or_create_impl_device_id_t<xsi_shared_memory_file_wrapper>
|
||||
{
|
||||
typedef xsi_key type;
|
||||
};
|
||||
|
||||
#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
|
||||
|
||||
/// @endcond
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class DeviceAbstraction, bool FileBased = true>
|
||||
|
||||
template <bool StoreDevice, class DeviceAbstraction>
|
||||
class managed_open_or_create_impl_device_holder
|
||||
{
|
||||
public:
|
||||
DeviceAbstraction &get_device()
|
||||
{ static DeviceAbstraction dev; return dev; }
|
||||
|
||||
const DeviceAbstraction &get_device() const
|
||||
{ static DeviceAbstraction dev; return dev; }
|
||||
};
|
||||
|
||||
template <class DeviceAbstraction>
|
||||
class managed_open_or_create_impl_device_holder<true, DeviceAbstraction>
|
||||
{
|
||||
public:
|
||||
DeviceAbstraction &get_device()
|
||||
{ return dev; }
|
||||
|
||||
const DeviceAbstraction &get_device() const
|
||||
{ return dev; }
|
||||
|
||||
private:
|
||||
DeviceAbstraction dev;
|
||||
};
|
||||
|
||||
template<class DeviceAbstraction, bool FileBased = true, bool StoreDevice = true>
|
||||
class managed_open_or_create_impl
|
||||
: public managed_open_or_create_impl_device_holder<StoreDevice, DeviceAbstraction>
|
||||
{
|
||||
//Non-copyable
|
||||
BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(managed_open_or_create_impl)
|
||||
|
||||
typedef typename managed_open_or_create_impl_device_id_t<DeviceAbstraction>::type device_id_t;
|
||||
typedef managed_open_or_create_impl_device_holder<StoreDevice, DeviceAbstraction> DevHolder;
|
||||
enum
|
||||
{
|
||||
UninitializedSegment,
|
||||
@@ -59,15 +109,15 @@ class managed_open_or_create_impl
|
||||
{}
|
||||
|
||||
managed_open_or_create_impl(create_only_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const permissions &perm)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoCreate
|
||||
, id
|
||||
, size
|
||||
, mode
|
||||
, addr
|
||||
@@ -76,13 +126,13 @@ class managed_open_or_create_impl
|
||||
}
|
||||
|
||||
managed_open_or_create_impl(open_only_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
mode_t mode,
|
||||
const void *addr)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoOpen
|
||||
, id
|
||||
, 0
|
||||
, mode
|
||||
, addr
|
||||
@@ -92,15 +142,15 @@ class managed_open_or_create_impl
|
||||
|
||||
|
||||
managed_open_or_create_impl(open_or_create_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const permissions &perm)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoOpenOrCreate
|
||||
, id
|
||||
, size
|
||||
, mode
|
||||
, addr
|
||||
@@ -110,16 +160,16 @@ class managed_open_or_create_impl
|
||||
|
||||
template <class ConstructFunc>
|
||||
managed_open_or_create_impl(create_only_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const ConstructFunc &construct_func,
|
||||
const permissions &perm)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
(detail::DoCreate
|
||||
, id
|
||||
, size
|
||||
, mode
|
||||
, addr
|
||||
@@ -129,14 +179,14 @@ class managed_open_or_create_impl
|
||||
|
||||
template <class ConstructFunc>
|
||||
managed_open_or_create_impl(open_only_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const ConstructFunc &construct_func)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoOpen
|
||||
, id
|
||||
, 0
|
||||
, mode
|
||||
, addr
|
||||
@@ -146,16 +196,16 @@ class managed_open_or_create_impl
|
||||
|
||||
template <class ConstructFunc>
|
||||
managed_open_or_create_impl(open_or_create_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const ConstructFunc &construct_func,
|
||||
const permissions &perm)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoOpenOrCreate
|
||||
, id
|
||||
, size
|
||||
, mode
|
||||
, addr
|
||||
@@ -190,20 +240,22 @@ class managed_open_or_create_impl
|
||||
|
||||
void swap(managed_open_or_create_impl &other)
|
||||
{
|
||||
this->m_name.swap(other.m_name);
|
||||
this->m_mapped_region.swap(other.m_mapped_region);
|
||||
}
|
||||
|
||||
const char *get_name() const
|
||||
{ return m_name.c_str(); }
|
||||
|
||||
bool flush()
|
||||
{ return m_mapped_region.flush(); }
|
||||
|
||||
|
||||
const mapped_region &get_mapped_region() const
|
||||
{ return m_mapped_region; }
|
||||
|
||||
|
||||
DeviceAbstraction &get_device()
|
||||
{ return this->DevHolder::get_device(); }
|
||||
|
||||
const DeviceAbstraction &get_device() const
|
||||
{ return this->DevHolder::get_device(); }
|
||||
|
||||
private:
|
||||
|
||||
//These are templatized to allow explicit instantiations
|
||||
@@ -217,22 +269,24 @@ class managed_open_or_create_impl
|
||||
|
||||
//These are templatized to allow explicit instantiations
|
||||
template<bool dummy>
|
||||
static void create_device(DeviceAbstraction &dev, const char *name, std::size_t size, const permissions &perm, detail::false_)
|
||||
static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t size, const permissions &perm, detail::false_)
|
||||
{
|
||||
DeviceAbstraction tmp(create_only, name, read_write, size, perm);
|
||||
DeviceAbstraction tmp(create_only, id, read_write, size, perm);
|
||||
tmp.swap(dev);
|
||||
}
|
||||
|
||||
template<bool dummy>
|
||||
static void create_device(DeviceAbstraction &dev, const char *name, std::size_t, const permissions &perm, detail::true_)
|
||||
static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t, const permissions &perm, detail::true_)
|
||||
{
|
||||
DeviceAbstraction tmp(create_only, name, read_write, perm);
|
||||
DeviceAbstraction tmp(create_only, id, read_write, perm);
|
||||
tmp.swap(dev);
|
||||
}
|
||||
|
||||
template <class ConstructFunc> inline
|
||||
void priv_open_or_create
|
||||
(detail::create_enum_t type, std::size_t size,
|
||||
(detail::create_enum_t type,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode, const void *addr,
|
||||
const permissions &perm,
|
||||
ConstructFunc construct_func)
|
||||
@@ -250,24 +304,24 @@ class managed_open_or_create_impl
|
||||
}
|
||||
|
||||
if(type == detail::DoOpen && mode == read_write){
|
||||
DeviceAbstraction tmp(open_only, m_name.c_str(), read_write);
|
||||
DeviceAbstraction tmp(open_only, id, read_write);
|
||||
tmp.swap(dev);
|
||||
created = false;
|
||||
}
|
||||
else if(type == detail::DoOpen && mode == read_only){
|
||||
DeviceAbstraction tmp(open_only, m_name.c_str(), read_only);
|
||||
DeviceAbstraction tmp(open_only, id, read_only);
|
||||
tmp.swap(dev);
|
||||
created = false;
|
||||
ronly = true;
|
||||
}
|
||||
else if(type == detail::DoOpen && mode == copy_on_write){
|
||||
DeviceAbstraction tmp(open_only, m_name.c_str(), read_only);
|
||||
DeviceAbstraction tmp(open_only, id, read_only);
|
||||
tmp.swap(dev);
|
||||
created = false;
|
||||
cow = true;
|
||||
}
|
||||
else if(type == detail::DoCreate){
|
||||
create_device<FileBased>(dev, m_name.c_str(), size, perm, file_like_t());
|
||||
create_device<FileBased>(dev, id, size, perm, file_like_t());
|
||||
created = true;
|
||||
}
|
||||
else if(type == detail::DoOpenOrCreate){
|
||||
@@ -278,7 +332,7 @@ class managed_open_or_create_impl
|
||||
bool completed = false;
|
||||
while(!completed){
|
||||
try{
|
||||
create_device<FileBased>(dev, m_name.c_str(), size, perm, file_like_t());
|
||||
create_device<FileBased>(dev, id, size, perm, file_like_t());
|
||||
created = true;
|
||||
completed = true;
|
||||
}
|
||||
@@ -288,7 +342,7 @@ class managed_open_or_create_impl
|
||||
}
|
||||
else{
|
||||
try{
|
||||
DeviceAbstraction tmp(open_only, m_name.c_str(), read_write);
|
||||
DeviceAbstraction tmp(open_only, id, read_write);
|
||||
dev.swap(tmp);
|
||||
created = false;
|
||||
completed = true;
|
||||
@@ -376,6 +430,9 @@ class managed_open_or_create_impl
|
||||
//All ok, just move resources to the external mapped region
|
||||
m_mapped_region.swap(region);
|
||||
}
|
||||
if(StoreDevice){
|
||||
this->DevHolder::get_device() = boost::interprocess::move(dev);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -384,7 +441,6 @@ class managed_open_or_create_impl
|
||||
{ detail::interprocess_tester::dont_close_on_destruction(m_mapped_region); }
|
||||
|
||||
mapped_region m_mapped_region;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
template<class DeviceAbstraction>
|
||||
|
||||
@@ -93,7 +93,7 @@ inline const char *get_temporary_path()
|
||||
|
||||
|
||||
inline file_handle_t create_new_file
|
||||
(const char *name, mode_t mode, const permissions & perm, bool temporary = false)
|
||||
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
|
||||
{
|
||||
unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
|
||||
return winapi::create_file
|
||||
@@ -102,7 +102,7 @@ inline file_handle_t create_new_file
|
||||
}
|
||||
|
||||
inline file_handle_t create_or_open_file
|
||||
(const char *name, mode_t mode, const permissions & perm, bool temporary = false)
|
||||
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
|
||||
{
|
||||
unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
|
||||
return winapi::create_file
|
||||
@@ -395,7 +395,7 @@ inline const char *get_temporary_path()
|
||||
}
|
||||
|
||||
inline file_handle_t create_new_file
|
||||
(const char *name, mode_t mode, const permissions & perm, bool temporary = false)
|
||||
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
|
||||
{
|
||||
(void)temporary;
|
||||
int ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
|
||||
@@ -406,12 +406,23 @@ inline file_handle_t create_new_file
|
||||
}
|
||||
|
||||
inline file_handle_t create_or_open_file
|
||||
(const char *name, mode_t mode, const permissions & perm, bool temporary = false)
|
||||
{
|
||||
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
|
||||
{
|
||||
(void)temporary;
|
||||
int ret = ::open(name, ((int)mode) | O_CREAT, perm.get_permissions());
|
||||
if(ret >= 0){
|
||||
::fchmod(ret, perm.get_permissions());
|
||||
int ret = -1;
|
||||
//We need a loop to change permissions correctly using fchmod, since
|
||||
//with "O_CREAT only" ::open we don't know if we've created or opened the file.
|
||||
while(1){
|
||||
ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
|
||||
if(ret >= 0){
|
||||
::fchmod(ret, perm.get_permissions());
|
||||
break;
|
||||
}
|
||||
else if(errno == EEXIST){
|
||||
if((ret = ::open(name, (int)mode)) >= 0 || errno != ENOENT){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -420,7 +431,7 @@ inline file_handle_t open_existing_file
|
||||
(const char *name, mode_t mode, bool temporary = false)
|
||||
{
|
||||
(void)temporary;
|
||||
return ::open(name, (int)mode, 0666);
|
||||
return ::open(name, (int)mode);
|
||||
}
|
||||
|
||||
inline bool delete_file(const char *name)
|
||||
|
||||
@@ -154,6 +154,7 @@ static const long BootAndSystemstampLength = 16;
|
||||
static const long BootstampLength = 8;
|
||||
static const unsigned long MaxPath = 260;
|
||||
|
||||
|
||||
//Keys
|
||||
static void * const hkey_local_machine = (void*)(unsigned long*)(long)(0x80000002);
|
||||
static unsigned long key_query_value = 0x0001;
|
||||
@@ -165,7 +166,10 @@ const long EOAC_NONE_IG = 0;
|
||||
const long CLSCTX_INPROC_SERVER_IG = 0x1;
|
||||
const long CLSCTX_LOCAL_SERVER_IG = 0x4;
|
||||
const long WBEM_FLAG_RETURN_IMMEDIATELY_IG = 0x10;
|
||||
const long WBEM_INFINITE_IG = 0xffffffff;
|
||||
const long WBEM_INFINITE_IG = 0xffffffffL;
|
||||
const long RPC_E_TOO_LATE_IG = 0x80010119L;
|
||||
const long S_OK_IG = 0L;
|
||||
const long S_FALSE_IG = 1;
|
||||
|
||||
} //namespace winapi {
|
||||
} //namespace interprocess {
|
||||
@@ -1448,33 +1452,54 @@ inline void get_registry_value(const char *folder, const char *value_key, std::v
|
||||
}
|
||||
}
|
||||
|
||||
struct co_uninitializer
|
||||
{ ~co_uninitializer() { CoUninitialize(); } };
|
||||
|
||||
template<class Object>
|
||||
struct com_releaser
|
||||
{
|
||||
Object *&object_;
|
||||
com_releaser(Object *&object) : object_(object) {}
|
||||
~com_releaser() { object_->Release(); object_ = 0; }
|
||||
};
|
||||
|
||||
inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_class, const wchar_t *wmi_class_var)
|
||||
{
|
||||
CoInitialize(0);
|
||||
|
||||
//See example http://msdn.microsoft.com/en-us/library/aa390423%28v=VS.85%29.aspx
|
||||
long co_init_ret = CoInitialize(0);
|
||||
if(co_init_ret != S_OK_IG && co_init_ret != S_FALSE_IG)
|
||||
return false;
|
||||
co_uninitializer co_initialize_end;
|
||||
|
||||
bool bRet = false;
|
||||
|
||||
if( 0 == CoInitializeSecurity( 0, -1, 0, 0, RPC_C_AUTHN_LEVEL_PKT_IG, RPC_C_IMP_LEVEL_IMPERSONATE_IG, 0, EOAC_NONE_IG, 0 ) )
|
||||
long sec_init_ret = CoInitializeSecurity
|
||||
( 0 //pVoid
|
||||
,-1 //cAuthSvc
|
||||
, 0 //asAuthSvc
|
||||
, 0 //pReserved1
|
||||
, RPC_C_AUTHN_LEVEL_PKT_IG //dwAuthnLevel
|
||||
, RPC_C_IMP_LEVEL_IMPERSONATE_IG //dwImpLevel
|
||||
, 0 //pAuthList
|
||||
, EOAC_NONE_IG //dwCapabilities
|
||||
, 0 //pReserved3
|
||||
);
|
||||
if( 0 == sec_init_ret || RPC_E_TOO_LATE_IG == sec_init_ret)
|
||||
{
|
||||
IWbemLocator_IG * pIWbemLocator = 0;
|
||||
|
||||
IWbemServices_IG * pWbemServices = 0;
|
||||
IEnumWbemClassObject_IG * pEnumObject = 0;
|
||||
|
||||
const wchar_t * bstrNamespace = L"root\\cimv2";
|
||||
|
||||
if( 0 != CoCreateInstance(
|
||||
CLSID_WbemAdministrativeLocator,
|
||||
0,
|
||||
CLSCTX_INPROC_SERVER_IG | CLSCTX_LOCAL_SERVER_IG,
|
||||
IID_IUnknown,
|
||||
( void ** )&pIWbemLocator
|
||||
)
|
||||
)
|
||||
{
|
||||
IID_IUnknown, (void **)&pIWbemLocator)){
|
||||
return false;
|
||||
}
|
||||
|
||||
com_releaser<IWbemLocator_IG> IWbemLocator_releaser(pIWbemLocator);
|
||||
|
||||
IWbemServices_IG *pWbemServices = 0;
|
||||
|
||||
if( 0 != pIWbemLocator->ConnectServer(
|
||||
bstrNamespace, // Namespace
|
||||
0, // Userid
|
||||
@@ -1485,19 +1510,20 @@ inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_
|
||||
0, // Context
|
||||
&pWbemServices
|
||||
)
|
||||
)
|
||||
{
|
||||
pIWbemLocator->Release();
|
||||
|
||||
){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
com_releaser<IWbemServices_IG> IWbemServices_releaser(pWbemServices);
|
||||
|
||||
strValue.clear();
|
||||
strValue += L"Select ";
|
||||
strValue += wmi_class_var;
|
||||
strValue += L" from ";
|
||||
strValue += wmi_class;
|
||||
|
||||
IEnumWbemClassObject_IG * pEnumObject = 0;
|
||||
|
||||
if ( 0 != pWbemServices->ExecQuery(
|
||||
L"WQL",
|
||||
strValue.c_str(),
|
||||
@@ -1505,47 +1531,30 @@ inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_
|
||||
0,
|
||||
&pEnumObject
|
||||
)
|
||||
)
|
||||
{
|
||||
pIWbemLocator->Release();
|
||||
pWbemServices->Release();
|
||||
|
||||
){
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long uCount = 1, uReturned;
|
||||
IWbemClassObject_IG * pClassObject = 0;
|
||||
|
||||
if ( 0 != pEnumObject->Reset() )
|
||||
{
|
||||
pIWbemLocator->Release();
|
||||
pWbemServices->Release();
|
||||
pEnumObject->Release();
|
||||
|
||||
|
||||
com_releaser<IEnumWbemClassObject_IG> IEnumWbemClassObject_releaser(pEnumObject);
|
||||
|
||||
if ( 0 != pEnumObject->Reset() ){
|
||||
return false;
|
||||
}
|
||||
|
||||
wchar_variant vwchar;
|
||||
|
||||
unsigned long uCount = 1, uReturned;
|
||||
IWbemClassObject_IG * pClassObject = 0;
|
||||
while( 0 == pEnumObject->Next( WBEM_INFINITE_IG, uCount, &pClassObject, &uReturned ) )
|
||||
{
|
||||
if ( 0 == pClassObject->Get( L"LastBootUpTime", 0, &vwchar, 0, 0 ) )
|
||||
{
|
||||
com_releaser<IWbemClassObject_IG> IWbemClassObject_releaser(pClassObject);
|
||||
if ( 0 == pClassObject->Get( L"LastBootUpTime", 0, &vwchar, 0, 0 ) ){
|
||||
bRet = true;
|
||||
strValue = vwchar.value.pbstrVal;
|
||||
VariantClear(&vwchar );
|
||||
break;
|
||||
strValue = vwchar.value.pbstrVal;
|
||||
VariantClear(&vwchar );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pIWbemLocator->Release();
|
||||
pWbemServices->Release();
|
||||
pEnumObject->Release();
|
||||
pClassObject->Release();
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2009-2010. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
|
||||
#include <boost/interprocess/detail/xsi_shared_memory.hpp>
|
||||
#include <boost/interprocess/xsi_shared_memory.hpp>
|
||||
#include <boost/interprocess/sync/xsi/xsi_named_mutex.hpp>
|
||||
#include <boost/interprocess/mapped_region.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
@@ -45,13 +45,10 @@ namespace interprocess {
|
||||
class xsi_shared_memory_device
|
||||
{
|
||||
/// @cond
|
||||
//Non-copyable and non-assignable
|
||||
xsi_shared_memory_device(xsi_shared_memory_device &);
|
||||
xsi_shared_memory_device &operator=(xsi_shared_memory_device &);
|
||||
/// @endcond
|
||||
BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory_file_wrapper)
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(xsi_shared_memory_device)
|
||||
|
||||
xsi_shared_memory_device();
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2010. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_FILE_WRAPPER_HPP
|
||||
#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_FILE_WRAPPER_HPP
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
|
||||
#error "This header can't be used in operating systems without XSI (System V) shared memory support"
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
|
||||
#include <boost/interprocess/xsi_shared_memory.hpp>
|
||||
|
||||
//!\file
|
||||
//!Describes a class representing a pseudo-file implemented on top of xsi shared memory.
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
class xsi_shared_memory_file_wrapper
|
||||
: public xsi_shared_memory
|
||||
{
|
||||
/// @cond
|
||||
BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory_file_wrapper)
|
||||
/// @endcond
|
||||
public:
|
||||
|
||||
xsi_shared_memory_file_wrapper() : xsi_shared_memory() {}
|
||||
|
||||
xsi_shared_memory_file_wrapper(create_only_t, const xsi_key &key, mode_t mode, std::size_t size, const permissions& perm = permissions())
|
||||
: xsi_shared_memory(create_only_t(), key, size, perm.get_permissions())
|
||||
{}
|
||||
|
||||
xsi_shared_memory_file_wrapper(open_or_create_t, const xsi_key &key, mode_t mode, std::size_t size, const permissions& perm = permissions())
|
||||
: xsi_shared_memory(open_or_create_t(), key, size, perm.get_permissions())
|
||||
{}
|
||||
|
||||
xsi_shared_memory_file_wrapper(open_only_t, const xsi_key &key, mode_t mode, const permissions& perm = permissions())
|
||||
: xsi_shared_memory(open_only_t(), key)
|
||||
{}
|
||||
|
||||
xsi_shared_memory_file_wrapper(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory_file_wrapper) moved)
|
||||
{ this->swap(moved); }
|
||||
|
||||
xsi_shared_memory_file_wrapper &operator=(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory_file_wrapper) moved)
|
||||
{
|
||||
xsi_shared_memory_file_wrapper tmp(boost::interprocess::move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Swaps two xsi_shared_memory_file_wrapper. Does not throw
|
||||
void swap(xsi_shared_memory_file_wrapper &other)
|
||||
{ this->xsi_shared_memory::swap(other); }
|
||||
};
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_FILE_WRAPPER_HPP
|
||||
@@ -67,7 +67,7 @@ class permissions;
|
||||
|
||||
class shared_memory_object;
|
||||
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
class windows_shared_memory;
|
||||
#endif //#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
@@ -239,7 +239,7 @@ wmanaged_shared_memory;
|
||||
// Windows shared memory managed memory classes
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
template <class CharType
|
||||
,class MemoryAlgorithm
|
||||
@@ -258,9 +258,10 @@ typedef basic_managed_windows_shared_memory
|
||||
,iset_index>
|
||||
wmanaged_windows_shared_memory;
|
||||
|
||||
#else
|
||||
#endif //#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
|
||||
template <class CharType
|
||||
,class MemoryAlgorithm
|
||||
,template<class IndexConfig> class IndexType>
|
||||
@@ -277,9 +278,8 @@ typedef basic_managed_xsi_shared_memory
|
||||
,rbtree_best_fit<mutex_family>
|
||||
,iset_index>
|
||||
wmanaged_xsi_shared_memory;
|
||||
#endif //#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
|
||||
|
||||
#endif //#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
#endif //#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Fixed address shared memory
|
||||
|
||||
189
include/boost/interprocess/managed_xsi_shared_memory.hpp
Normal file
189
include/boost/interprocess/managed_xsi_shared_memory.hpp
Normal file
@@ -0,0 +1,189 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_MANAGED_XSI_SHARED_MEMORY_HPP
|
||||
#define BOOST_INTERPROCESS_MANAGED_XSI_SHARED_MEMORY_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
|
||||
#error "This header can't be used in operating systems without XSI (System V) shared memory support"
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/managed_memory_impl.hpp>
|
||||
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
|
||||
#include <boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace interprocess {
|
||||
|
||||
//!A basic X/Open System Interface (XSI) shared memory named object creation class. Initializes the
|
||||
//!shared memory segment. Inherits all basic functionality from
|
||||
//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>*/
|
||||
template
|
||||
<
|
||||
class CharType,
|
||||
class AllocationAlgorithm,
|
||||
template<class IndexConfig> class IndexType
|
||||
>
|
||||
class basic_managed_xsi_shared_memory
|
||||
: public detail::basic_managed_memory_impl
|
||||
<CharType, AllocationAlgorithm, IndexType
|
||||
,detail::managed_open_or_create_impl<xsi_shared_memory_file_wrapper, false, true>::ManagedOpenOrCreateUserOffset>
|
||||
, private detail::managed_open_or_create_impl<xsi_shared_memory_file_wrapper, false, true>
|
||||
{
|
||||
/// @cond
|
||||
public:
|
||||
typedef xsi_shared_memory_file_wrapper device_type;
|
||||
|
||||
public:
|
||||
typedef detail::managed_open_or_create_impl
|
||||
<xsi_shared_memory_file_wrapper, false, true> base2_t;
|
||||
typedef detail::basic_managed_memory_impl
|
||||
<CharType, AllocationAlgorithm, IndexType,
|
||||
base2_t::ManagedOpenOrCreateUserOffset> base_t;
|
||||
|
||||
typedef detail::create_open_func<base_t> create_open_func_t;
|
||||
|
||||
basic_managed_xsi_shared_memory *get_this_pointer()
|
||||
{ return this; }
|
||||
|
||||
private:
|
||||
typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
|
||||
BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(basic_managed_xsi_shared_memory)
|
||||
/// @endcond
|
||||
|
||||
public: //functions
|
||||
|
||||
//!Destroys *this and indicates that the calling process is finished using
|
||||
//!the resource. The destructor function will deallocate
|
||||
//!any system resources allocated by the system for use by this process for
|
||||
//!this resource. The resource can still be opened again calling
|
||||
//!the open constructor overload. To erase the resource from the system
|
||||
//!use remove().
|
||||
~basic_managed_xsi_shared_memory()
|
||||
{}
|
||||
|
||||
//!Default constructor. Does nothing.
|
||||
//!Useful in combination with move semantics
|
||||
basic_managed_xsi_shared_memory()
|
||||
{}
|
||||
|
||||
//!Creates shared memory and creates and places the segment manager.
|
||||
//!This can throw.
|
||||
basic_managed_xsi_shared_memory(create_only_t create_only, const xsi_key &key,
|
||||
std::size_t size, const void *addr = 0, const permissions& perm = permissions())
|
||||
: base_t()
|
||||
, base2_t(create_only, key, size, read_write, addr,
|
||||
create_open_func_t(get_this_pointer(), detail::DoCreate), perm)
|
||||
{}
|
||||
|
||||
//!Creates shared memory and creates and places the segment manager if
|
||||
//!segment was not created. If segment was created it connects to the
|
||||
//!segment.
|
||||
//!This can throw.
|
||||
basic_managed_xsi_shared_memory (open_or_create_t open_or_create,
|
||||
const xsi_key &key, std::size_t size,
|
||||
const void *addr = 0, const permissions& perm = permissions())
|
||||
: base_t()
|
||||
, base2_t(open_or_create, key, size, read_write, addr,
|
||||
create_open_func_t(get_this_pointer(),
|
||||
detail::DoOpenOrCreate), perm)
|
||||
{}
|
||||
|
||||
//!Connects to a created shared memory and its segment manager.
|
||||
//!in read-only mode.
|
||||
//!This can throw.
|
||||
basic_managed_xsi_shared_memory (open_read_only_t, const xsi_key &key,
|
||||
const void *addr = 0)
|
||||
: base_t()
|
||||
, base2_t(open_only, key, read_only, addr,
|
||||
create_open_func_t(get_this_pointer(),
|
||||
detail::DoOpen))
|
||||
{}
|
||||
|
||||
//!Connects to a created shared memory and its segment manager.
|
||||
//!This can throw.
|
||||
basic_managed_xsi_shared_memory (open_only_t open_only, const xsi_key &key,
|
||||
const void *addr = 0)
|
||||
: base_t()
|
||||
, base2_t(open_only, key, read_write, addr,
|
||||
create_open_func_t(get_this_pointer(),
|
||||
detail::DoOpen))
|
||||
{}
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this.
|
||||
//!Does not throw
|
||||
basic_managed_xsi_shared_memory(BOOST_INTERPROCESS_RV_REF(basic_managed_xsi_shared_memory) moved)
|
||||
{
|
||||
basic_managed_xsi_shared_memory tmp;
|
||||
this->swap(moved);
|
||||
tmp.swap(moved);
|
||||
}
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this.
|
||||
//!Does not throw
|
||||
basic_managed_xsi_shared_memory &operator=(BOOST_INTERPROCESS_RV_REF(basic_managed_xsi_shared_memory) moved)
|
||||
{
|
||||
basic_managed_xsi_shared_memory tmp(boost::interprocess::move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Swaps the ownership of the managed shared memories managed by *this and other.
|
||||
//!Never throws.
|
||||
void swap(basic_managed_xsi_shared_memory &other)
|
||||
{
|
||||
base_t::swap(other);
|
||||
base2_t::swap(other);
|
||||
}
|
||||
|
||||
//!Erases a XSI shared memory object identified by shmid
|
||||
//!from the system.
|
||||
//!Returns false on error. Never throws
|
||||
static bool remove(int shmid)
|
||||
{ return device_type::remove(shmid); }
|
||||
|
||||
int get_shmid() const
|
||||
{ return base2_t::get_device().get_shmid(); }
|
||||
|
||||
/// @cond
|
||||
|
||||
//!Tries to find a previous named allocation address. Returns a memory
|
||||
//!buffer and the object count. If not found returned pointer is 0.
|
||||
//!Never throws.
|
||||
template <class T>
|
||||
std::pair<T*, std::size_t> find (char_ptr_holder_t name)
|
||||
{
|
||||
if(base2_t::get_mapped_region().get_mode() == read_only){
|
||||
return base_t::template find_no_lock<T>(name);
|
||||
}
|
||||
else{
|
||||
return base_t::template find<T>(name);
|
||||
}
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_MANAGED_XSI_SHARED_MEMORY_HPP
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
#ifndef BOOST_INTERPROCESS_PERMISSIONS_HPP
|
||||
#define BOOST_INTERPROCESS_PERMISSIONS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
/// @cond
|
||||
|
||||
#if defined (_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -25,12 +27,16 @@
|
||||
|
||||
#endif
|
||||
|
||||
/// @endcond
|
||||
|
||||
//!\file
|
||||
//!Describes permissions class
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
namespace detail {
|
||||
@@ -48,18 +54,22 @@ winapi::interprocess_all_access_security unrestricted_permissions_holder<Dummy>:
|
||||
|
||||
#endif //defined BOOST_INTERPROCESS_WINDOWS
|
||||
|
||||
/// @endcond
|
||||
|
||||
//!The permissions class represents permissions to be set to shared memory or
|
||||
//!files, that can be constructed form usual permission representations:
|
||||
//!a SECURITY_ATTRIBUTES pointer in windows or ORed rwx chmod integer in UNIX.
|
||||
class permissions
|
||||
{
|
||||
/// @cond
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
typedef void* os_permissions_type;
|
||||
#else
|
||||
typedef int os_permissions_type;
|
||||
#endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
|
||||
#endif
|
||||
os_permissions_type m_perm;
|
||||
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
@@ -80,22 +90,26 @@ class permissions
|
||||
//!for UNIX.
|
||||
void set_default()
|
||||
{
|
||||
#if (defined BOOST_INTERPROCESS_WINDOWS)
|
||||
/// @cond
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
m_perm = 0;
|
||||
#else
|
||||
m_perm = 0644;
|
||||
#endif
|
||||
/// @endcond
|
||||
}
|
||||
|
||||
//!Sets permissions to unrestricted access:
|
||||
//!A null DACL for windows or 0666 for UNIX.
|
||||
void set_unrestricted()
|
||||
{
|
||||
#if (defined BOOST_INTERPROCESS_WINDOWS)
|
||||
/// @cond
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
m_perm = &detail::unrestricted_permissions_holder<0>::unrestricted;
|
||||
#else
|
||||
m_perm = 0666;
|
||||
#endif
|
||||
/// @endcond
|
||||
}
|
||||
|
||||
//!Sets permissions from a user provided os-dependent
|
||||
@@ -115,3 +129,4 @@ class permissions
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_PERMISSIONS_HPP
|
||||
|
||||
|
||||
@@ -298,29 +298,48 @@ inline bool shared_memory_object::priv_open_or_create
|
||||
error_info err(mode_error);
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
int unix_perm = perm.get_permissions();
|
||||
|
||||
switch(type){
|
||||
case detail::DoOpen:
|
||||
//No addition
|
||||
{
|
||||
//No oflag addition
|
||||
m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
|
||||
}
|
||||
break;
|
||||
case detail::DoCreate:
|
||||
{
|
||||
oflag |= (O_CREAT | O_EXCL);
|
||||
m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
|
||||
if(m_handle >= 0){
|
||||
::fchmod(m_handle, unix_perm);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case detail::DoOpenOrCreate:
|
||||
{
|
||||
oflag |= O_CREAT;
|
||||
//We need a loop to change permissions correctly using fchmod, since
|
||||
//with "O_CREAT only" shm_open we don't know if we've created or opened the file.
|
||||
while(1){
|
||||
m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
|
||||
if(m_handle >= 0){
|
||||
::fchmod(m_handle, unix_perm);
|
||||
break;
|
||||
}
|
||||
else if(errno == EEXIST){
|
||||
if((m_handle = shm_open(m_filename.c_str(), oflag, unix_perm)) >= 0 || errno != ENOENT){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
error_info err = other_error;
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
|
||||
//Open file using POSIX API
|
||||
m_handle = shm_open(m_filename.c_str(), oflag, perm.get_permissions());
|
||||
|
||||
if(m_handle >= 0){
|
||||
::fchmod(m_handle, perm.get_permissions());
|
||||
{
|
||||
error_info err = other_error;
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
|
||||
//Check for error
|
||||
|
||||
87
include/boost/interprocess/xsi_key.hpp
Normal file
87
include/boost/interprocess/xsi_key.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_XSI_KEY_HPP
|
||||
#define BOOST_INTERPROCESS_XSI_KEY_HPP
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
|
||||
#error "This header can't be used in operating systems without XSI (System V) shared memory support"
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
//!\file
|
||||
//!Describes a class representing a xsi key type.
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
//!A class that wraps XSI (System V) key_t type.
|
||||
//!This type calculates key_t from path and id using ftok
|
||||
//!or sets key to IPC_PRIVATE using the default constructor.
|
||||
class xsi_key
|
||||
{
|
||||
public:
|
||||
|
||||
//!Default constructor.
|
||||
//!Represents a private xsi_key.
|
||||
xsi_key()
|
||||
: m_key(IPC_PRIVATE)
|
||||
{}
|
||||
|
||||
//!Creates a new XSI shared memory with a key obtained from a call to ftok (with path
|
||||
//!"path" and id "id"), of size "size" and permissions "perm".
|
||||
//!If the shared memory previously exists, throws an error.
|
||||
xsi_key(const char *path, boost::uint8_t id)
|
||||
{
|
||||
key_t key;
|
||||
if(path){
|
||||
key = ::ftok(path, id);
|
||||
if(((key_t)-1) == key){
|
||||
error_info err = system_error_code();
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
else{
|
||||
key = IPC_PRIVATE;
|
||||
}
|
||||
m_key = key;
|
||||
}
|
||||
|
||||
//!Returns the internal key_t value
|
||||
key_t get_key() const
|
||||
{ return m_key; }
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
key_t m_key;
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_XSI_KEY_HPP
|
||||
@@ -15,20 +15,22 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
#error "This header can't be used in Windows operating systems"
|
||||
#if !defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
|
||||
#error "This header can't be used in operating systems without XSI (System V) shared memory support"
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/xsi_key.hpp>
|
||||
#include <boost/interprocess/permissions.hpp>
|
||||
#include <sys/shm.h>
|
||||
#include <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <string>
|
||||
|
||||
//!\file
|
||||
//!Describes a class representing a native xsi shared memory.
|
||||
@@ -38,10 +40,7 @@ namespace interprocess {
|
||||
|
||||
//!A class that wraps XSI (System V) shared memory.
|
||||
//!Unlike shared_memory_object, xsi_shared_memory needs a valid
|
||||
//!path and a 8 bit key to identify a shared memory create
|
||||
//!when all processes destroy all their xsi_shared_memory
|
||||
//!objects and mapped regions for the same shared memory
|
||||
//!or the processes end/crash.
|
||||
//!xsi_key to identify a shared memory object.
|
||||
//!
|
||||
//!Warning: XSI shared memory and interprocess portable
|
||||
//!shared memory (boost::interprocess::shared_memory_object)
|
||||
@@ -50,40 +49,40 @@ class xsi_shared_memory
|
||||
{
|
||||
/// @cond
|
||||
//Non-copyable and non-assignable
|
||||
xsi_shared_memory(xsi_shared_memory &);
|
||||
xsi_shared_memory &operator=(xsi_shared_memory &);
|
||||
BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory)
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(xsi_shared_memory)
|
||||
|
||||
//!Default constructor.
|
||||
//!Represents an empty xsi_shared_memory.
|
||||
xsi_shared_memory();
|
||||
|
||||
//!Creates a new XSI shared memory with a key obtained from a call to ftok (with path
|
||||
//!"path" and id "id"), of size "size" and permissions "perm".
|
||||
//!Initializes *this with a shmid previously obtained (possibly from another process)
|
||||
//!This lower-level initializer allows shared memory mapping without having a key.
|
||||
xsi_shared_memory(open_only_t, int shmid)
|
||||
: m_shmid (shmid)
|
||||
{}
|
||||
|
||||
//!Creates a new XSI shared memory from 'key', with size "size" and permissions "perm".
|
||||
//!If the shared memory previously exists, throws an error.
|
||||
xsi_shared_memory(create_only_t, const char *path, boost::uint8_t id, std::size_t size, int perm = 0666)
|
||||
{ this->priv_open_or_create(detail::DoCreate, path, id, perm, size); }
|
||||
xsi_shared_memory(create_only_t, const xsi_key &key, std::size_t size, const permissions& perm = permissions())
|
||||
{ this->priv_open_or_create(detail::DoCreate, key, perm, size); }
|
||||
|
||||
//!Tries to create a new XSI shared memory with a key obtained from a call to ftok (with path
|
||||
//!"path" and id "id"), of size "size" and permissions "perm".
|
||||
//!If the shared memory previously exists, it tries to open it.
|
||||
//!Otherwise throws an error.
|
||||
xsi_shared_memory(open_or_create_t, const char *path, boost::uint8_t id, std::size_t size, int perm = 0666)
|
||||
{ this->priv_open_or_create(detail::DoOpenOrCreate, path, id, perm, size); }
|
||||
//!Opens an existing shared memory with identifier 'key' or creates a new XSI shared memory from
|
||||
//!identifier 'key', with size "size" and permissions "perm".
|
||||
xsi_shared_memory(open_or_create_t, const xsi_key &key, std::size_t size, const permissions& perm = permissions())
|
||||
{ this->priv_open_or_create(detail::DoOpenOrCreate, key, perm, size); }
|
||||
|
||||
//!Tries to open a XSI shared memory with a key obtained from a call to ftok (with path
|
||||
//!"path" and id "id") and permissions "perm".
|
||||
//!Tries to open a XSI shared memory with identifier 'key'
|
||||
//!If the shared memory does not previously exist, it throws an error.
|
||||
xsi_shared_memory(open_only_t, const char *path, boost::uint8_t id, int perm = 0666)
|
||||
{ this->priv_open_or_create(detail::DoOpen, path, id, perm, 0); }
|
||||
xsi_shared_memory(open_only_t, const xsi_key &key)
|
||||
{ this->priv_open_or_create(detail::DoOpen, key, permissions(), 0); }
|
||||
|
||||
//!Moves the ownership of "moved"'s shared memory object to *this.
|
||||
//!After the call, "moved" does not represent any shared memory object.
|
||||
//!Does not throw
|
||||
xsi_shared_memory(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory) moved)
|
||||
: m_shmid(-1)
|
||||
{ this->swap(moved); }
|
||||
|
||||
//!Moves the ownership of "moved"'s shared memory to *this.
|
||||
@@ -103,18 +102,10 @@ class xsi_shared_memory
|
||||
//!this connection to it. Use remove() to destroy the shared memory.
|
||||
~xsi_shared_memory();
|
||||
|
||||
//!Returns the path used to
|
||||
//!obtain the key.
|
||||
const char *get_path() const;
|
||||
|
||||
//!Returns the shared memory ID that
|
||||
//!identifies the shared memory
|
||||
int get_shmid() const;
|
||||
|
||||
//!Returns access
|
||||
//!permissions
|
||||
int get_permissions() const;
|
||||
|
||||
//!Returns the mapping handle.
|
||||
//!Never throws
|
||||
mapping_handle_t get_mapping_handle() const;
|
||||
@@ -129,9 +120,8 @@ class xsi_shared_memory
|
||||
|
||||
//!Closes a previously opened file mapping. Never throws.
|
||||
bool priv_open_or_create( detail::create_enum_t type
|
||||
, const char *filename
|
||||
, boost::uint8_t id
|
||||
, int perm
|
||||
, const xsi_key &key
|
||||
, const permissions& perm
|
||||
, std::size_t size);
|
||||
int m_shmid;
|
||||
/// @endcond
|
||||
@@ -158,20 +148,9 @@ inline mapping_handle_t xsi_shared_memory::get_mapping_handle() const
|
||||
{ mapping_handle_t mhnd = { m_shmid, true}; return mhnd; }
|
||||
|
||||
inline bool xsi_shared_memory::priv_open_or_create
|
||||
(detail::create_enum_t type, const char *filename, boost::uint8_t id, int perm, std::size_t size)
|
||||
(detail::create_enum_t type, const xsi_key &key, const permissions& permissions, std::size_t size)
|
||||
{
|
||||
key_t key;
|
||||
if(filename){
|
||||
key = ::ftok(filename, id);
|
||||
if(((key_t)-1) == key){
|
||||
error_info err = system_error_code();
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
else{
|
||||
key = IPC_PRIVATE;
|
||||
}
|
||||
|
||||
int perm = permissions.get_permissions();
|
||||
perm &= 0x01FF;
|
||||
int shmflg = perm;
|
||||
|
||||
@@ -192,7 +171,7 @@ inline bool xsi_shared_memory::priv_open_or_create
|
||||
}
|
||||
}
|
||||
|
||||
int ret = ::shmget(key, size, shmflg);
|
||||
int ret = ::shmget(key.get_key(), size, shmflg);
|
||||
int shmid = ret;
|
||||
if((type == detail::DoOpen) && (-1 != ret)){
|
||||
//Now get the size
|
||||
Reference in New Issue
Block a user