Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67449 - in trunk/boost/interprocess: . containers detail
From: igaztanaga_at_[hidden]
Date: 2010-12-26 04:48:00


Author: igaztanaga
Date: 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
New Revision: 67449
URL: http://svn.boost.org/trac/boost/changeset/67449

Log:
Added XSI shared memory
Added:
   trunk/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp (contents, props changed)
   trunk/boost/interprocess/managed_xsi_shared_memory.hpp (contents, props changed)
   trunk/boost/interprocess/xsi_key.hpp (contents, props changed)
   trunk/boost/interprocess/xsi_shared_memory.hpp (contents, props changed)
Removed:
   trunk/boost/interprocess/detail/xsi_shared_memory.hpp
Text files modified:
   trunk/boost/interprocess/containers/containers_fwd.hpp | 2
   trunk/boost/interprocess/detail/file_wrapper.hpp | 1
   trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp | 116 +++++++++++++++++++++++++++++----------
   trunk/boost/interprocess/detail/os_file_functions.hpp | 29 ++++++---
   trunk/boost/interprocess/detail/win32_api.hpp | 105 +++++++++++++++++++----------------
   trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp | 11 +--
   trunk/boost/interprocess/interprocess_fwd.hpp | 12 ++--
   trunk/boost/interprocess/permissions.hpp | 25 ++++++-
   trunk/boost/interprocess/shared_memory_object.hpp | 43 ++++++++++----
   9 files changed, 227 insertions(+), 117 deletions(-)

Modified: trunk/boost/interprocess/containers/containers_fwd.hpp
==============================================================================
--- trunk/boost/interprocess/containers/containers_fwd.hpp (original)
+++ trunk/boost/interprocess/containers/containers_fwd.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -35,4 +35,6 @@
 
 #include <boost/interprocess/detail/config_end.hpp>
 
+/// @endcond
+
 #endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_CONTAINERS_FWD_HPP

Modified: trunk/boost/interprocess/detail/file_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/detail/file_wrapper.hpp (original)
+++ trunk/boost/interprocess/detail/file_wrapper.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -53,6 +53,7 @@
    //!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.

Modified: trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp (original)
+++ trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -30,16 +30,66 @@
 
 /// @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 @@
    {}
 
    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 @@
    }
 
    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 @@
 
 
    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 @@
 
    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 @@
 
    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 @@
 
    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 @@
 
    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 @@
 
    //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 @@
       }
 
       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 @@
          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 @@
                }
                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 @@
          //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 @@
    { detail::interprocess_tester::dont_close_on_destruction(m_mapped_region); }
 
    mapped_region m_mapped_region;
- std::string m_name;
 };
 
 template<class DeviceAbstraction>

Modified: trunk/boost/interprocess/detail/os_file_functions.hpp
==============================================================================
--- trunk/boost/interprocess/detail/os_file_functions.hpp (original)
+++ trunk/boost/interprocess/detail/os_file_functions.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -93,7 +93,7 @@
 
 
 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_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 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_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 @@
    (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)

Modified: trunk/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- trunk/boost/interprocess/detail/win32_api.hpp (original)
+++ trunk/boost/interprocess/detail/win32_api.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -154,6 +154,7 @@
 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 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 @@
    }
 }
 
+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 @@
             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 @@
             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;
 }
 

Deleted: trunk/boost/interprocess/detail/xsi_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/detail/xsi_shared_memory.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
+++ (empty file)
@@ -1,222 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (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_SHARED_MEMORY_HPP
-#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#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"
-#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/interprocess_fwd.hpp>
-#include <boost/interprocess/exceptions.hpp>
-#include <sys/shm.h>
-#include <cstddef>
-#include <boost/cstdint.hpp>
-#include <string>
-
-//!\file
-//!Describes a class representing a native xsi shared memory.
-
-namespace boost {
-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.
-//!
-//!Warning: XSI shared memory and interprocess portable
-//!shared memory (boost::interprocess::shared_memory_object)
-//!can't communicate between them.
-class xsi_shared_memory
-{
- /// @cond
- //Non-copyable and non-assignable
- xsi_shared_memory(xsi_shared_memory &);
- xsi_shared_memory &operator=(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".
- //!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); }
-
- //!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); }
-
- //!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".
- //!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); }
-
- //!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)
- { this->swap(moved); }
-
- //!Moves the ownership of "moved"'s shared memory to *this.
- //!After the call, "moved" does not represent any shared memory.
- //!Does not throw
- xsi_shared_memory &operator=(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory) moved)
- {
- xsi_shared_memory tmp(boost::interprocess::move(moved));
- this->swap(tmp);
- return *this;
- }
-
- //!Swaps two xsi_shared_memorys. Does not throw
- void swap(xsi_shared_memory &other);
-
- //!Destroys *this. The shared memory won't be destroyed, just
- //!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;
-
- //!Erases the XSI shared memory object identified by shmid
- //!from the system.
- //!Returns false on error. Never throws
- static bool remove(int shmid);
-
- /// @cond
- private:
-
- //!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
- , std::size_t size);
- int m_shmid;
- /// @endcond
-};
-
-/// @cond
-
-inline xsi_shared_memory::xsi_shared_memory()
- : m_shmid(-1)
-{}
-
-inline xsi_shared_memory::~xsi_shared_memory()
-{}
-
-inline int xsi_shared_memory::get_shmid() const
-{ return m_shmid; }
-
-inline void xsi_shared_memory::swap(xsi_shared_memory &other)
-{
- std::swap(m_shmid, other.m_shmid);
-}
-
-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)
-{
- 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;
- }
-
- perm &= 0x01FF;
- int shmflg = perm;
-
- switch(type){
- case detail::DoOpen:
- shmflg |= 0;
- break;
- case detail::DoCreate:
- shmflg |= IPC_CREAT | IPC_EXCL;
- break;
- case detail::DoOpenOrCreate:
- shmflg |= IPC_CREAT;
- break;
- default:
- {
- error_info err = other_error;
- throw interprocess_exception(err);
- }
- }
-
- int ret = ::shmget(key, size, shmflg);
- int shmid = ret;
- if((type == detail::DoOpen) && (-1 != ret)){
- //Now get the size
- ::shmid_ds xsi_ds;
- ret = ::shmctl(ret, IPC_STAT, &xsi_ds);
- size = xsi_ds.shm_segsz;
- }
- if(-1 == ret){
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
-
- m_shmid = shmid;
- return true;
-}
-
-inline bool xsi_shared_memory::remove(int shmid)
-{ return -1 != ::shmctl(shmid, IPC_RMID, 0); }
-
-///@endcond
-
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP

Modified: trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp
==============================================================================
--- trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp (original)
+++ trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -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 @@
 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();
 

Added: trunk/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -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

Modified: trunk/boost/interprocess/interprocess_fwd.hpp
==============================================================================
--- trunk/boost/interprocess/interprocess_fwd.hpp (original)
+++ trunk/boost/interprocess/interprocess_fwd.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -67,7 +67,7 @@
 
 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 @@
 // 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 @@
    ,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 @@
    ,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

Added: trunk/boost/interprocess/managed_xsi_shared_memory.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/managed_xsi_shared_memory.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -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
+

Modified: trunk/boost/interprocess/permissions.hpp
==============================================================================
--- trunk/boost/interprocess/permissions.hpp (original)
+++ trunk/boost/interprocess/permissions.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -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 @@
 
 #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 @@
    //!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 @@
 #include <boost/interprocess/detail/config_end.hpp>
 
 #endif //BOOST_INTERPROCESS_PERMISSIONS_HPP
+

Modified: trunk/boost/interprocess/shared_memory_object.hpp
==============================================================================
--- trunk/boost/interprocess/shared_memory_object.hpp (original)
+++ trunk/boost/interprocess/shared_memory_object.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -298,29 +298,48 @@
       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

Added: trunk/boost/interprocess/xsi_key.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/xsi_key.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -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

Added: trunk/boost/interprocess/xsi_shared_memory.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/xsi_shared_memory.hpp 2010-12-26 04:47:54 EST (Sun, 26 Dec 2010)
@@ -0,0 +1,201 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_SHARED_MEMORY_HPP
+#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_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 <boost/interprocess/xsi_key.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <sys/shm.h>
+#include <cstddef>
+#include <boost/cstdint.hpp>
+
+//!\file
+//!Describes a class representing a native xsi shared memory.
+
+namespace boost {
+namespace interprocess {
+
+//!A class that wraps XSI (System V) shared memory.
+//!Unlike shared_memory_object, xsi_shared_memory needs a valid
+//!xsi_key to identify a shared memory object.
+//!
+//!Warning: XSI shared memory and interprocess portable
+//!shared memory (boost::interprocess::shared_memory_object)
+//!can't communicate between them.
+class xsi_shared_memory
+{
+ /// @cond
+ //Non-copyable and non-assignable
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory)
+ /// @endcond
+
+ public:
+ //!Default constructor.
+ //!Represents an empty xsi_shared_memory.
+ xsi_shared_memory();
+
+ //!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 xsi_key &key, std::size_t size, const permissions& perm = permissions())
+ { this->priv_open_or_create(detail::DoCreate, key, 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 identifier 'key'
+ //!If the shared memory does not previously exist, it throws an error.
+ 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.
+ //!After the call, "moved" does not represent any shared memory.
+ //!Does not throw
+ xsi_shared_memory &operator=(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory) moved)
+ {
+ xsi_shared_memory tmp(boost::interprocess::move(moved));
+ this->swap(tmp);
+ return *this;
+ }
+
+ //!Swaps two xsi_shared_memorys. Does not throw
+ void swap(xsi_shared_memory &other);
+
+ //!Destroys *this. The shared memory won't be destroyed, just
+ //!this connection to it. Use remove() to destroy the shared memory.
+ ~xsi_shared_memory();
+
+ //!Returns the shared memory ID that
+ //!identifies the shared memory
+ int get_shmid() const;
+
+ //!Returns the mapping handle.
+ //!Never throws
+ mapping_handle_t get_mapping_handle() const;
+
+ //!Erases the XSI shared memory object identified by shmid
+ //!from the system.
+ //!Returns false on error. Never throws
+ static bool remove(int shmid);
+
+ /// @cond
+ private:
+
+ //!Closes a previously opened file mapping. Never throws.
+ bool priv_open_or_create( detail::create_enum_t type
+ , const xsi_key &key
+ , const permissions& perm
+ , std::size_t size);
+ int m_shmid;
+ /// @endcond
+};
+
+/// @cond
+
+inline xsi_shared_memory::xsi_shared_memory()
+ : m_shmid(-1)
+{}
+
+inline xsi_shared_memory::~xsi_shared_memory()
+{}
+
+inline int xsi_shared_memory::get_shmid() const
+{ return m_shmid; }
+
+inline void xsi_shared_memory::swap(xsi_shared_memory &other)
+{
+ std::swap(m_shmid, other.m_shmid);
+}
+
+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 xsi_key &key, const permissions& permissions, std::size_t size)
+{
+ int perm = permissions.get_permissions();
+ perm &= 0x01FF;
+ int shmflg = perm;
+
+ switch(type){
+ case detail::DoOpen:
+ shmflg |= 0;
+ break;
+ case detail::DoCreate:
+ shmflg |= IPC_CREAT | IPC_EXCL;
+ break;
+ case detail::DoOpenOrCreate:
+ shmflg |= IPC_CREAT;
+ break;
+ default:
+ {
+ error_info err = other_error;
+ throw interprocess_exception(err);
+ }
+ }
+
+ int ret = ::shmget(key.get_key(), size, shmflg);
+ int shmid = ret;
+ if((type == detail::DoOpen) && (-1 != ret)){
+ //Now get the size
+ ::shmid_ds xsi_ds;
+ ret = ::shmctl(ret, IPC_STAT, &xsi_ds);
+ size = xsi_ds.shm_segsz;
+ }
+ if(-1 == ret){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+
+ m_shmid = shmid;
+ return true;
+}
+
+inline bool xsi_shared_memory::remove(int shmid)
+{ return -1 != ::shmctl(shmid, IPC_RMID, 0); }
+
+///@endcond
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk