diff options
Diffstat (limited to 'boost/interprocess/detail/managed_open_or_create_impl.hpp')
-rw-r--r-- | boost/interprocess/detail/managed_open_or_create_impl.hpp | 65 |
1 files changed, 39 insertions, 26 deletions
diff --git a/boost/interprocess/detail/managed_open_or_create_impl.hpp b/boost/interprocess/detail/managed_open_or_create_impl.hpp index a4f1f15817..bd08be56d3 100644 --- a/boost/interprocess/detail/managed_open_or_create_impl.hpp +++ b/boost/interprocess/detail/managed_open_or_create_impl.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost +// (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) // @@ -11,6 +11,10 @@ #ifndef BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL #define BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL +#if defined(_MSC_VER) +# 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> @@ -25,13 +29,14 @@ #include <boost/interprocess/permissions.hpp> #include <boost/type_traits/alignment_of.hpp> #include <boost/type_traits/type_with_alignment.hpp> +#include <boost/interprocess/sync/spin/wait.hpp> #include <boost/move/move.hpp> #include <boost/cstdint.hpp> namespace boost { namespace interprocess { -/// @cond +#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) namespace ipcdetail{ class interprocess_tester; } @@ -48,13 +53,13 @@ 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 + +#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED namespace ipcdetail { @@ -79,12 +84,12 @@ class managed_open_or_create_impl_device_holder<true, DeviceAbstraction> const DeviceAbstraction &get_device() const { return dev; } - + private: DeviceAbstraction dev; }; -template<class DeviceAbstraction, std::size_t MemAlignment = 0, bool FileBased = true, bool StoreDevice = true> +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> { @@ -94,9 +99,9 @@ class 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, + { + UninitializedSegment, + InitializingSegment, InitializedSegment, CorruptedSegment }; @@ -222,10 +227,10 @@ class managed_open_or_create_impl { 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; + return *this; } ~managed_open_or_create_impl() @@ -309,14 +314,18 @@ class managed_open_or_create_impl { typedef bool_<FileBased> file_like_t; (void)mode; - error_info err; bool created = false; bool ronly = false; bool cow = false; DeviceAbstraction dev; - if(type != DoOpen && size < ManagedOpenOrCreateUserOffset){ - throw interprocess_exception(error_info(size_error)); + 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())){ @@ -349,6 +358,7 @@ class managed_open_or_create_impl //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()); @@ -366,8 +376,8 @@ class managed_open_or_create_impl created = false; completed = true; } - catch(interprocess_exception &ex){ - if(ex.get_error_code() != not_found_error){ + catch(interprocess_exception &e){ + if(e.get_error_code() != not_found_error){ throw; } } @@ -379,7 +389,7 @@ class managed_open_or_create_impl catch(...){ throw; } - thread_yield(); + swait.yield(); } } @@ -426,11 +436,13 @@ class managed_open_or_create_impl 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)){ - throw interprocess_exception(error_info(system_error_code())); + error_info err = system_error_code(); + throw interprocess_exception(err); } - thread_yield(); + swait.yield(); } if(filesize == 1){ throw interprocess_exception(error_info(corrupted_error)); @@ -442,8 +454,9 @@ class managed_open_or_create_impl 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){ - thread_yield(); + swait.yield(); value = atomic_read32(patomic_word); } @@ -461,6 +474,11 @@ class managed_open_or_create_impl } } + 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() @@ -469,11 +487,6 @@ class managed_open_or_create_impl mapped_region m_mapped_region; }; -template<class DeviceAbstraction> -inline void swap(managed_open_or_create_impl<DeviceAbstraction> &x - ,managed_open_or_create_impl<DeviceAbstraction> &y) -{ x.swap(y); } - } //namespace ipcdetail { } //namespace interprocess { |