502 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			502 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								//////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// (C) Copyright Ion Gaztanaga 2006-2012. 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_OPEN_OR_CREATE_IMPL
							 | 
						||
| 
								 | 
							
								#define BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BOOST_CONFIG_HPP
							 | 
						||
| 
								 | 
							
								#  include <boost/config.hpp>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#if defined(BOOST_HAS_PRAGMA_ONCE)
							 | 
						||
| 
								 | 
							
								#  pragma once
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/detail/config_begin.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/detail/os_thread_functions.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/detail/os_file_functions.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/creation_tags.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/mapped_region.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/detail/utilities.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/detail/type_traits.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/detail/atomic.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/detail/interprocess_tester.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/creation_tags.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/detail/mpl.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/permissions.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/container/detail/type_traits.hpp>  //alignment_of, aligned_storage
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/sync/spin/wait.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/move/move.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/cstdint.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost {
							 | 
						||
| 
								 | 
							
								namespace interprocess {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
							 | 
						||
| 
								 | 
							
								namespace ipcdetail{ 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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace ipcdetail {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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, std::size_t MemAlignment, bool FileBased, bool StoreDevice>
							 | 
						||
| 
								 | 
							
								class managed_open_or_create_impl
							 | 
						||
| 
								 | 
							
								   : public managed_open_or_create_impl_device_holder<StoreDevice, DeviceAbstraction>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   //Non-copyable
							 | 
						||
| 
								 | 
							
								   BOOST_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,
							 | 
						||
| 
								 | 
							
								      InitializingSegment,
							 | 
						||
| 
								 | 
							
								      InitializedSegment,
							 | 
						||
| 
								 | 
							
								      CorruptedSegment
							 | 
						||
| 
								 | 
							
								   };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   public:
							 | 
						||
| 
								 | 
							
								   static const std::size_t
							 | 
						||
| 
								 | 
							
								      ManagedOpenOrCreateUserOffset =
							 | 
						||
| 
								 | 
							
								         ct_rounded_size
							 | 
						||
| 
								 | 
							
								            < sizeof(boost::uint32_t)
							 | 
						||
| 
								 | 
							
								            , MemAlignment ? (MemAlignment) :
							 | 
						||
| 
								 | 
							
								               (::boost::container::container_detail::alignment_of
							 | 
						||
| 
								 | 
							
								                  < ::boost::container::container_detail::max_align_t >::value)
							 | 
						||
| 
								 | 
							
								            >::value;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   managed_open_or_create_impl()
							 | 
						||
| 
								 | 
							
								   {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   managed_open_or_create_impl(create_only_t,
							 | 
						||
| 
								 | 
							
								                 const device_id_t & id,
							 | 
						||
| 
								 | 
							
								                 std::size_t size,
							 | 
						||
| 
								 | 
							
								                 mode_t mode,
							 | 
						||
| 
								 | 
							
								                 const void *addr,
							 | 
						||
| 
								 | 
							
								                 const permissions &perm)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      priv_open_or_create
							 | 
						||
| 
								 | 
							
								         ( DoCreate
							 | 
						||
| 
								 | 
							
								         , id
							 | 
						||
| 
								 | 
							
								         , size
							 | 
						||
| 
								 | 
							
								         , mode
							 | 
						||
| 
								 | 
							
								         , addr
							 | 
						||
| 
								 | 
							
								         , perm
							 | 
						||
| 
								 | 
							
								         , null_mapped_region_function());
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   managed_open_or_create_impl(open_only_t,
							 | 
						||
| 
								 | 
							
								                 const device_id_t & id,
							 | 
						||
| 
								 | 
							
								                 mode_t mode,
							 | 
						||
| 
								 | 
							
								                 const void *addr)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      priv_open_or_create
							 | 
						||
| 
								 | 
							
								         ( DoOpen
							 | 
						||
| 
								 | 
							
								         , id
							 | 
						||
| 
								 | 
							
								         , 0
							 | 
						||
| 
								 | 
							
								         , mode
							 | 
						||
| 
								 | 
							
								         , addr
							 | 
						||
| 
								 | 
							
								         , permissions()
							 | 
						||
| 
								 | 
							
								         , null_mapped_region_function());
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   managed_open_or_create_impl(open_or_create_t,
							 | 
						||
| 
								 | 
							
								                 const device_id_t & id,
							 | 
						||
| 
								 | 
							
								                 std::size_t size,
							 | 
						||
| 
								 | 
							
								                 mode_t mode,
							 | 
						||
| 
								 | 
							
								                 const void *addr,
							 | 
						||
| 
								 | 
							
								                 const permissions &perm)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      priv_open_or_create
							 | 
						||
| 
								 | 
							
								         ( DoOpenOrCreate
							 | 
						||
| 
								 | 
							
								         , id
							 | 
						||
| 
								 | 
							
								         , size
							 | 
						||
| 
								 | 
							
								         , mode
							 | 
						||
| 
								 | 
							
								         , addr
							 | 
						||
| 
								 | 
							
								         , perm
							 | 
						||
| 
								 | 
							
								         , null_mapped_region_function());
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class ConstructFunc>
							 | 
						||
| 
								 | 
							
								   managed_open_or_create_impl(create_only_t,
							 | 
						||
| 
								 | 
							
								                 const device_id_t & id,
							 | 
						||
| 
								 | 
							
								                 std::size_t size,
							 | 
						||
| 
								 | 
							
								                 mode_t mode,
							 | 
						||
| 
								 | 
							
								                 const void *addr,
							 | 
						||
| 
								 | 
							
								                 const ConstructFunc &construct_func,
							 | 
						||
| 
								 | 
							
								                 const permissions &perm)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      priv_open_or_create
							 | 
						||
| 
								 | 
							
								         (DoCreate
							 | 
						||
| 
								 | 
							
								         , id
							 | 
						||
| 
								 | 
							
								         , size
							 | 
						||
| 
								 | 
							
								         , mode
							 | 
						||
| 
								 | 
							
								         , addr
							 | 
						||
| 
								 | 
							
								         , perm
							 | 
						||
| 
								 | 
							
								         , construct_func);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class ConstructFunc>
							 | 
						||
| 
								 | 
							
								   managed_open_or_create_impl(open_only_t,
							 | 
						||
| 
								 | 
							
								                 const device_id_t & id,
							 | 
						||
| 
								 | 
							
								                 mode_t mode,
							 | 
						||
| 
								 | 
							
								                 const void *addr,
							 | 
						||
| 
								 | 
							
								                 const ConstructFunc &construct_func)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      priv_open_or_create
							 | 
						||
| 
								 | 
							
								         ( DoOpen
							 | 
						||
| 
								 | 
							
								         , id
							 | 
						||
| 
								 | 
							
								         , 0
							 | 
						||
| 
								 | 
							
								         , mode
							 | 
						||
| 
								 | 
							
								         , addr
							 | 
						||
| 
								 | 
							
								         , permissions()
							 | 
						||
| 
								 | 
							
								         , construct_func);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class ConstructFunc>
							 | 
						||
| 
								 | 
							
								   managed_open_or_create_impl(open_or_create_t,
							 | 
						||
| 
								 | 
							
								                 const device_id_t & id,
							 | 
						||
| 
								 | 
							
								                 std::size_t size,
							 | 
						||
| 
								 | 
							
								                 mode_t mode,
							 | 
						||
| 
								 | 
							
								                 const void *addr,
							 | 
						||
| 
								 | 
							
								                 const ConstructFunc &construct_func,
							 | 
						||
| 
								 | 
							
								                 const permissions &perm)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      priv_open_or_create
							 | 
						||
| 
								 | 
							
								         ( DoOpenOrCreate
							 | 
						||
| 
								 | 
							
								         , id
							 | 
						||
| 
								 | 
							
								         , size
							 | 
						||
| 
								 | 
							
								         , mode
							 | 
						||
| 
								 | 
							
								         , addr
							 | 
						||
| 
								 | 
							
								         , perm
							 | 
						||
| 
								 | 
							
								         , construct_func);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   managed_open_or_create_impl(BOOST_RV_REF(managed_open_or_create_impl) moved)
							 | 
						||
| 
								 | 
							
								   {  this->swap(moved);   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   managed_open_or_create_impl &operator=(BOOST_RV_REF(managed_open_or_create_impl) moved)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      managed_open_or_create_impl tmp(boost::move(moved));
							 | 
						||
| 
								 | 
							
								      this->swap(tmp);
							 | 
						||
| 
								 | 
							
								      return *this;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   ~managed_open_or_create_impl()
							 | 
						||
| 
								 | 
							
								   {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   std::size_t get_user_size()  const
							 | 
						||
| 
								 | 
							
								   {  return m_mapped_region.get_size() - ManagedOpenOrCreateUserOffset; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   void *get_user_address()  const
							 | 
						||
| 
								 | 
							
								   {  return static_cast<char*>(m_mapped_region.get_address()) + ManagedOpenOrCreateUserOffset;  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   std::size_t get_real_size()  const
							 | 
						||
| 
								 | 
							
								   {  return m_mapped_region.get_size(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   void *get_real_address()  const
							 | 
						||
| 
								 | 
							
								   {  return m_mapped_region.get_address();  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   void swap(managed_open_or_create_impl &other)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      this->m_mapped_region.swap(other.m_mapped_region);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   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
							 | 
						||
| 
								 | 
							
								   template<bool dummy>
							 | 
						||
| 
								 | 
							
								   static void truncate_device(DeviceAbstraction &, offset_t, false_)
							 | 
						||
| 
								 | 
							
								   {} //Empty
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template<bool dummy>
							 | 
						||
| 
								 | 
							
								   static void truncate_device(DeviceAbstraction &dev, offset_t size, true_)
							 | 
						||
| 
								 | 
							
								   {  dev.truncate(size);  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template<bool dummy>
							 | 
						||
| 
								 | 
							
								   static bool check_offset_t_size(std::size_t , false_)
							 | 
						||
| 
								 | 
							
								   { return true; } //Empty
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template<bool dummy>
							 | 
						||
| 
								 | 
							
								   static bool check_offset_t_size(std::size_t size, true_)
							 | 
						||
| 
								 | 
							
								   { return size == std::size_t(offset_t(size)); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //These are templatized to allow explicit instantiations
							 | 
						||
| 
								 | 
							
								   template<bool dummy>
							 | 
						||
| 
								 | 
							
								   static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t size, const permissions &perm, false_ file_like)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      (void)file_like;
							 | 
						||
| 
								 | 
							
								      DeviceAbstraction tmp(create_only, id, read_write, size, perm);
							 | 
						||
| 
								 | 
							
								      tmp.swap(dev);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template<bool dummy>
							 | 
						||
| 
								 | 
							
								   static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t, const permissions &perm, true_ file_like)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      (void)file_like;
							 | 
						||
| 
								 | 
							
								      DeviceAbstraction tmp(create_only, id, read_write, perm);
							 | 
						||
| 
								 | 
							
								      tmp.swap(dev);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   template <class ConstructFunc> inline
							 | 
						||
| 
								 | 
							
								   void priv_open_or_create
							 | 
						||
| 
								 | 
							
								      (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)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      typedef bool_<FileBased> file_like_t;
							 | 
						||
| 
								 | 
							
								      (void)mode;
							 | 
						||
| 
								 | 
							
								      bool created = false;
							 | 
						||
| 
								 | 
							
								      bool ronly   = false;
							 | 
						||
| 
								 | 
							
								      bool cow     = false;
							 | 
						||
| 
								 | 
							
								      DeviceAbstraction dev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if(type != DoOpen){
							 | 
						||
| 
								 | 
							
								         //Check if the requested size is enough to build the managed metadata
							 | 
						||
| 
								 | 
							
								         const std::size_t func_min_size = construct_func.get_min_size();
							 | 
						||
| 
								 | 
							
								         if( (std::size_t(-1) - ManagedOpenOrCreateUserOffset) < func_min_size ||
							 | 
						||
| 
								 | 
							
								             size < (func_min_size + ManagedOpenOrCreateUserOffset) ){
							 | 
						||
| 
								 | 
							
								            throw interprocess_exception(error_info(size_error));
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      //Check size can be represented by offset_t (used by truncate)
							 | 
						||
| 
								 | 
							
								      if(type != DoOpen && !check_offset_t_size<FileBased>(size, file_like_t())){
							 | 
						||
| 
								 | 
							
								         throw interprocess_exception(error_info(size_error));
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if(type == DoOpen && mode == read_write){
							 | 
						||
| 
								 | 
							
								         DeviceAbstraction tmp(open_only, id, read_write);
							 | 
						||
| 
								 | 
							
								         tmp.swap(dev);
							 | 
						||
| 
								 | 
							
								         created = false;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      else if(type == DoOpen && mode == read_only){
							 | 
						||
| 
								 | 
							
								         DeviceAbstraction tmp(open_only, id, read_only);
							 | 
						||
| 
								 | 
							
								         tmp.swap(dev);
							 | 
						||
| 
								 | 
							
								         created = false;
							 | 
						||
| 
								 | 
							
								         ronly   = true;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      else if(type == DoOpen && mode == copy_on_write){
							 | 
						||
| 
								 | 
							
								         DeviceAbstraction tmp(open_only, id, read_only);
							 | 
						||
| 
								 | 
							
								         tmp.swap(dev);
							 | 
						||
| 
								 | 
							
								         created = false;
							 | 
						||
| 
								 | 
							
								         cow     = true;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      else if(type == DoCreate){
							 | 
						||
| 
								 | 
							
								         create_device<FileBased>(dev, id, size, perm, file_like_t());
							 | 
						||
| 
								 | 
							
								         created = true;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      else if(type == DoOpenOrCreate){
							 | 
						||
| 
								 | 
							
								         //This loop is very ugly, but brute force is sometimes better
							 | 
						||
| 
								 | 
							
								         //than diplomacy. If someone knows how to open or create a
							 | 
						||
| 
								 | 
							
								         //file and know if we have really created it or just open it
							 | 
						||
| 
								 | 
							
								         //drop me a e-mail!
							 | 
						||
| 
								 | 
							
								         bool completed = false;
							 | 
						||
| 
								 | 
							
								         spin_wait swait;
							 | 
						||
| 
								 | 
							
								         while(!completed){
							 | 
						||
| 
								 | 
							
								            try{
							 | 
						||
| 
								 | 
							
								               create_device<FileBased>(dev, id, size, perm, file_like_t());
							 | 
						||
| 
								 | 
							
								               created     = true;
							 | 
						||
| 
								 | 
							
								               completed   = true;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            catch(interprocess_exception &ex){
							 | 
						||
| 
								 | 
							
								               if(ex.get_error_code() != already_exists_error){
							 | 
						||
| 
								 | 
							
								                  throw;
							 | 
						||
| 
								 | 
							
								               }
							 | 
						||
| 
								 | 
							
								               else{
							 | 
						||
| 
								 | 
							
								                  try{
							 | 
						||
| 
								 | 
							
								                     DeviceAbstraction tmp(open_only, id, read_write);
							 | 
						||
| 
								 | 
							
								                     dev.swap(tmp);
							 | 
						||
| 
								 | 
							
								                     created     = false;
							 | 
						||
| 
								 | 
							
								                     completed   = true;
							 | 
						||
| 
								 | 
							
								                  }
							 | 
						||
| 
								 | 
							
								                  catch(interprocess_exception &e){
							 | 
						||
| 
								 | 
							
								                     if(e.get_error_code() != not_found_error){
							 | 
						||
| 
								 | 
							
								                        throw;
							 | 
						||
| 
								 | 
							
								                     }
							 | 
						||
| 
								 | 
							
								                  }
							 | 
						||
| 
								 | 
							
								                  catch(...){
							 | 
						||
| 
								 | 
							
								                     throw;
							 | 
						||
| 
								 | 
							
								                  }
							 | 
						||
| 
								 | 
							
								               }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            catch(...){
							 | 
						||
| 
								 | 
							
								               throw;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            swait.yield();
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if(created){
							 | 
						||
| 
								 | 
							
								         try{
							 | 
						||
| 
								 | 
							
								            //If this throws, we are lost
							 | 
						||
| 
								 | 
							
								            truncate_device<FileBased>(dev, size, file_like_t());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            //If the following throws, we will truncate the file to 1
							 | 
						||
| 
								 | 
							
								            mapped_region        region(dev, read_write, 0, 0, addr);
							 | 
						||
| 
								 | 
							
								            boost::uint32_t *patomic_word = 0;  //avoid gcc warning
							 | 
						||
| 
								 | 
							
								            patomic_word = static_cast<boost::uint32_t*>(region.get_address());
							 | 
						||
| 
								 | 
							
								            boost::uint32_t previous = atomic_cas32(patomic_word, InitializingSegment, UninitializedSegment);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(previous == UninitializedSegment){
							 | 
						||
| 
								 | 
							
								               try{
							 | 
						||
| 
								 | 
							
								                  construct_func( static_cast<char*>(region.get_address()) + ManagedOpenOrCreateUserOffset
							 | 
						||
| 
								 | 
							
								                                , size - ManagedOpenOrCreateUserOffset, true);
							 | 
						||
| 
								 | 
							
								                  //All ok, just move resources to the external mapped region
							 | 
						||
| 
								 | 
							
								                  m_mapped_region.swap(region);
							 | 
						||
| 
								 | 
							
								               }
							 | 
						||
| 
								 | 
							
								               catch(...){
							 | 
						||
| 
								 | 
							
								                  atomic_write32(patomic_word, CorruptedSegment);
							 | 
						||
| 
								 | 
							
								                  throw;
							 | 
						||
| 
								 | 
							
								               }
							 | 
						||
| 
								 | 
							
								               atomic_write32(patomic_word, InitializedSegment);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if(previous == InitializingSegment || previous == InitializedSegment){
							 | 
						||
| 
								 | 
							
								               throw interprocess_exception(error_info(already_exists_error));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else{
							 | 
						||
| 
								 | 
							
								               throw interprocess_exception(error_info(corrupted_error));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         catch(...){
							 | 
						||
| 
								 | 
							
								            try{
							 | 
						||
| 
								 | 
							
								               truncate_device<FileBased>(dev, 1u, file_like_t());
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            catch(...){
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            throw;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      else{
							 | 
						||
| 
								 | 
							
								         if(FileBased){
							 | 
						||
| 
								 | 
							
								            offset_t filesize = 0;
							 | 
						||
| 
								 | 
							
								            spin_wait swait;
							 | 
						||
| 
								 | 
							
								            while(filesize == 0){
							 | 
						||
| 
								 | 
							
								               if(!get_file_size(file_handle_from_mapping_handle(dev.get_mapping_handle()), filesize)){
							 | 
						||
| 
								 | 
							
								                  error_info err = system_error_code();
							 | 
						||
| 
								 | 
							
								                  throw interprocess_exception(err);
							 | 
						||
| 
								 | 
							
								               }
							 | 
						||
| 
								 | 
							
								               swait.yield();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if(filesize == 1){
							 | 
						||
| 
								 | 
							
								               throw interprocess_exception(error_info(corrupted_error));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         mapped_region  region(dev, ronly ? read_only : (cow ? copy_on_write : read_write), 0, 0, addr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         boost::uint32_t *patomic_word = static_cast<boost::uint32_t*>(region.get_address());
							 | 
						||
| 
								 | 
							
								         boost::uint32_t value = atomic_read32(patomic_word);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         spin_wait swait;
							 | 
						||
| 
								 | 
							
								         while(value == InitializingSegment || value == UninitializedSegment){
							 | 
						||
| 
								 | 
							
								            swait.yield();
							 | 
						||
| 
								 | 
							
								            value = atomic_read32(patomic_word);
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         if(value != InitializedSegment)
							 | 
						||
| 
								 | 
							
								            throw interprocess_exception(error_info(corrupted_error));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         construct_func( static_cast<char*>(region.get_address()) + ManagedOpenOrCreateUserOffset
							 | 
						||
| 
								 | 
							
								                        , region.get_size() - ManagedOpenOrCreateUserOffset
							 | 
						||
| 
								 | 
							
								                        , false);
							 | 
						||
| 
								 | 
							
								         //All ok, just move resources to the external mapped region
							 | 
						||
| 
								 | 
							
								         m_mapped_region.swap(region);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if(StoreDevice){
							 | 
						||
| 
								 | 
							
								         this->DevHolder::get_device() = boost::move(dev);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   friend void swap(managed_open_or_create_impl &left, managed_open_or_create_impl &right)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      left.swap(right);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   private:
							 | 
						||
| 
								 | 
							
								   friend class interprocess_tester;
							 | 
						||
| 
								 | 
							
								   void dont_close_on_destruction()
							 | 
						||
| 
								 | 
							
								   {  interprocess_tester::dont_close_on_destruction(m_mapped_region);  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   mapped_region     m_mapped_region;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}  //namespace ipcdetail {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}  //namespace interprocess {
							 | 
						||
| 
								 | 
							
								}  //namespace boost {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/interprocess/detail/config_end.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif   //#ifndef BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL
							 |