summaryrefslogtreecommitdiff
path: root/boost/interprocess/detail/managed_open_or_create_impl.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/detail/managed_open_or_create_impl.hpp')
-rw-r--r--boost/interprocess/detail/managed_open_or_create_impl.hpp65
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 {