mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
Fixes #10011 segment_manager::find( unique_instance_t* ) fails to compile
This commit is contained in:
@@ -6751,6 +6751,7 @@ thank them:
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9835 Trac #9835 (['"Boost Interprocess fails to compile with Android NDK GCC 4.8, -Werror=unused-variable"])].
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9911 Trac #9911 (['"get_tmp_base_dir(...) failure"])].
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9946 Trac #9946 (['"ret_ptr uninitialized in init_atomic_func, fini_atomic_func"])].
|
||||
* [@https://svn.boost.org/trac/boost/ticket/10011 Trac #10011 (['"segment_manager::find( unique_instance_t* ) fails to compile"])].
|
||||
* [@https://svn.boost.org/trac/boost/ticket/10021 Trac #10021 (['"Interprocess and BOOST_USE_WINDOWS_H"])].
|
||||
* [@https://github.com/boostorg/interprocess/pull/2 GitHub #2] (['"Provide support for the Cray C++ compiler. The Cray compiler defines __GNUC__"]]).
|
||||
* [@https://github.com/boostorg/interprocess/pull/3 GitHub #3] (['"Fix/mingw interprocess_exception throw in file_wrapper::priv_open_or_create"]]).
|
||||
|
||||
@@ -609,7 +609,7 @@ class basic_managed_memory_impl
|
||||
{ mp_header->template destroy_ptr<T>(ptr); }
|
||||
|
||||
//!Returns the name of an object created with construct/find_or_construct
|
||||
//!functions. Does not throw
|
||||
//!functions. If ptr points to an unique instance typeid(T).name() is returned.
|
||||
template<class T>
|
||||
static const char_type *get_instance_name(const T *ptr)
|
||||
{ return segment_manager::get_instance_name(ptr); }
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <string> //char_traits
|
||||
#include <new> //std::nothrow
|
||||
#include <utility> //std::pair
|
||||
#include <iterator> //std::iterator_traits
|
||||
#include <boost/assert.hpp> //BOOST_ASSERT
|
||||
#include <functional> //unary_function
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
@@ -323,6 +324,15 @@ class char_ptr_holder
|
||||
operator const CharType *()
|
||||
{ return m_name; }
|
||||
|
||||
const CharType *get() const
|
||||
{ return m_name; }
|
||||
|
||||
bool is_unique() const
|
||||
{ return m_name == reinterpret_cast<CharType*>(-1); }
|
||||
|
||||
bool is_anonymous() const
|
||||
{ return m_name == static_cast<CharType*>(0); }
|
||||
|
||||
private:
|
||||
const CharType *m_name;
|
||||
};
|
||||
@@ -472,12 +482,12 @@ class segment_manager_iterator_value_adaptor<Iterator, false>
|
||||
|
||||
template<class Iterator, bool intrusive>
|
||||
struct segment_manager_iterator_transform
|
||||
: std::unary_function< typename Iterator::value_type
|
||||
: std::unary_function< typename std::iterator_traits<Iterator>::value_type
|
||||
, segment_manager_iterator_value_adaptor<Iterator, intrusive> >
|
||||
{
|
||||
typedef segment_manager_iterator_value_adaptor<Iterator, intrusive> result_type;
|
||||
|
||||
result_type operator()(const typename Iterator::value_type &arg) const
|
||||
result_type operator()(const typename std::iterator_traits<Iterator>::value_type &arg) const
|
||||
{ return result_type(arg); }
|
||||
};
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@ template <class Iterator, class UnaryFunction>
|
||||
class transform_iterator
|
||||
: public UnaryFunction
|
||||
, public std::iterator
|
||||
< typename Iterator::iterator_category
|
||||
< typename std::iterator_traits<Iterator>::iterator_category
|
||||
, typename ipcdetail::remove_reference<typename UnaryFunction::result_type>::type
|
||||
, typename Iterator::difference_type
|
||||
, typename std::iterator_traits<Iterator>::difference_type
|
||||
, operator_arrow_proxy<typename UnaryFunction::result_type>
|
||||
, typename UnaryFunction::result_type>
|
||||
{
|
||||
@@ -115,33 +115,33 @@ class transform_iterator
|
||||
friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
|
||||
friend typename std::iterator_traits<Iterator>::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
transform_iterator& operator+=(typename Iterator::difference_type off)
|
||||
transform_iterator& operator+=(typename std::iterator_traits<Iterator>::difference_type off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
transform_iterator operator+(typename Iterator::difference_type off) const
|
||||
transform_iterator operator+(typename std::iterator_traits<Iterator>::difference_type off) const
|
||||
{
|
||||
transform_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
|
||||
friend transform_iterator operator+(typename std::iterator_traits<Iterator>::difference_type off, const transform_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
transform_iterator& operator-=(typename Iterator::difference_type off)
|
||||
transform_iterator& operator-=(typename std::iterator_traits<Iterator>::difference_type off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
transform_iterator operator-(typename Iterator::difference_type off) const
|
||||
transform_iterator operator-(typename std::iterator_traits<Iterator>::difference_type off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
typename UnaryFunction::result_type operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
typename UnaryFunction::result_type operator[](typename Iterator::difference_type off) const
|
||||
typename UnaryFunction::result_type operator[](typename std::iterator_traits<Iterator>::difference_type off) const
|
||||
{ return UnaryFunction::operator()(m_it[off]); }
|
||||
|
||||
operator_arrow_proxy<typename UnaryFunction::result_type>
|
||||
@@ -172,10 +172,10 @@ class transform_iterator
|
||||
typename UnaryFunction::result_type dereference() const
|
||||
{ return UnaryFunction::operator()(*m_it); }
|
||||
|
||||
void advance(typename Iterator::difference_type n)
|
||||
void advance(typename std::iterator_traits<Iterator>::difference_type n)
|
||||
{ std::advance(m_it, n); }
|
||||
|
||||
typename Iterator::difference_type distance_to(const transform_iterator &other)const
|
||||
typename std::iterator_traits<Iterator>::difference_type distance_to(const transform_iterator &other)const
|
||||
{ return std::distance(other.m_it, m_it); }
|
||||
};
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ class null_index
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
typedef void * iterator;
|
||||
typedef const void * const_iterator;
|
||||
typedef int * iterator;
|
||||
typedef const int * const_iterator;
|
||||
|
||||
//!begin() is equal
|
||||
//!to end()
|
||||
|
||||
@@ -188,6 +188,8 @@ class segment_manager_base
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class T>
|
||||
std::pair<T *, bool>
|
||||
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
|
||||
@@ -215,6 +217,8 @@ class segment_manager_base
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
|
||||
//!Deallocates the bytes allocated with allocate/allocate_many()
|
||||
//!pointed by addr
|
||||
void deallocate (void *addr)
|
||||
@@ -343,19 +347,19 @@ class segment_manager
|
||||
segment_manager();
|
||||
segment_manager(const segment_manager &);
|
||||
segment_manager &operator=(const segment_manager &);
|
||||
typedef segment_manager_base<MemoryAlgorithm> Base;
|
||||
typedef segment_manager_base<MemoryAlgorithm> segment_manager_base_t;
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
typedef MemoryAlgorithm memory_algorithm;
|
||||
typedef typename Base::void_pointer void_pointer;
|
||||
typedef typename Base::size_type size_type;
|
||||
typedef typename Base::difference_type difference_type;
|
||||
typedef CharType char_type;
|
||||
typedef MemoryAlgorithm memory_algorithm;
|
||||
typedef typename segment_manager_base_t::void_pointer void_pointer;
|
||||
typedef typename segment_manager_base_t::size_type size_type;
|
||||
typedef typename segment_manager_base_t::difference_type difference_type;
|
||||
typedef CharType char_type;
|
||||
|
||||
typedef segment_manager_base<MemoryAlgorithm> segment_manager_base_type;
|
||||
|
||||
static const size_type PayloadPerAllocation = Base::PayloadPerAllocation;
|
||||
static const size_type PayloadPerAllocation = segment_manager_base_t::PayloadPerAllocation;
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
@@ -379,7 +383,7 @@ class segment_manager
|
||||
,is_intrusive_index<index_type>::value> unique_transform;
|
||||
/// @endcond
|
||||
|
||||
typedef typename Base::mutex_family mutex_family;
|
||||
typedef typename segment_manager_base_t::mutex_family mutex_family;
|
||||
|
||||
typedef transform_iterator
|
||||
<typename named_index_t::const_iterator, named_transform> const_named_iterator;
|
||||
@@ -409,39 +413,31 @@ class segment_manager
|
||||
//!the segment manager is being constructed.
|
||||
//!Can throw
|
||||
explicit segment_manager(size_type segment_size)
|
||||
: Base(segment_size, priv_get_reserved_bytes())
|
||||
, m_header(static_cast<Base*>(get_this_pointer()))
|
||||
: segment_manager_base_t(segment_size, priv_get_reserved_bytes())
|
||||
, m_header(static_cast<segment_manager_base_t*>(get_this_pointer()))
|
||||
{
|
||||
(void) anonymous_instance; (void) unique_instance;
|
||||
BOOST_ASSERT(static_cast<const void*>(this) == static_cast<const void*>(static_cast<Base*>(this)));
|
||||
//Check EBO is applied, it's required
|
||||
const void * const this_addr = this;
|
||||
const void *const segm_addr = static_cast<segment_manager_base_t*>(this);
|
||||
(void)this_addr; (void)segm_addr;
|
||||
BOOST_ASSERT( this_addr == segm_addr);
|
||||
}
|
||||
|
||||
//!Tries to find a previous named allocation. Returns the address
|
||||
//!Tries to find a previous named/unique allocation. Returns the address
|
||||
//!and the object count. On failure the first member of the
|
||||
//!returned pair is 0.
|
||||
template <class T>
|
||||
std::pair<T*, size_type> find (const CharType* name)
|
||||
std::pair<T*, size_type> find (char_ptr_holder_t name)
|
||||
{ return this->priv_find_impl<T>(name, true); }
|
||||
|
||||
//!Tries to find a previous unique allocation. Returns the address
|
||||
//!and the object count. On failure the first member of the
|
||||
//!returned pair is 0.
|
||||
template <class T>
|
||||
std::pair<T*, size_type> find (const ipcdetail::unique_instance_t* name)
|
||||
{ return this->priv_find_impl<T>(name, true); }
|
||||
|
||||
//!Tries to find a previous named allocation. Returns the address
|
||||
//!Tries to find a previous named/unique allocation. Returns the address
|
||||
//!and the object count. On failure the first member of the
|
||||
//!returned pair is 0. This search is not mutex-protected!
|
||||
//!Use it only inside atomic_func() calls, where the internal mutex
|
||||
//!is guaranteed to be locked.
|
||||
template <class T>
|
||||
std::pair<T*, size_type> find_no_lock (const CharType* name)
|
||||
{ return this->priv_find_impl<T>(name, false); }
|
||||
|
||||
//!Tries to find a previous unique allocation. Returns the address
|
||||
//!and the object count. On failure the first member of the
|
||||
//!returned pair is 0. This search is not mutex-protected!
|
||||
template <class T>
|
||||
std::pair<T*, size_type> find_no_lock (const ipcdetail::unique_instance_t* name)
|
||||
std::pair<T*, size_type> find_no_lock (char_ptr_holder_t name)
|
||||
{ return this->priv_find_impl<T>(name, false); }
|
||||
|
||||
//!Returns throwing "construct" proxy
|
||||
@@ -500,7 +496,7 @@ class segment_manager
|
||||
|
||||
//!Calls object function blocking recursive interprocess_mutex and guarantees that
|
||||
//!no new named_alloc or destroy will be executed by any process while
|
||||
//!executing the object function call*/
|
||||
//!executing the object function call
|
||||
template <class Func>
|
||||
void atomic_func(Func &f)
|
||||
{ scoped_lock<rmutex> guard(m_header); f(); }
|
||||
@@ -523,28 +519,26 @@ class segment_manager
|
||||
}
|
||||
}
|
||||
|
||||
//!Destroys a previously created unique instance.
|
||||
//!Destroys a previously created named/unique instance.
|
||||
//!Returns false if the object was not present.
|
||||
template <class T>
|
||||
bool destroy(const ipcdetail::unique_instance_t *)
|
||||
bool destroy(char_ptr_holder_t name)
|
||||
{
|
||||
BOOST_ASSERT(!name.is_anonymous());
|
||||
ipcdetail::placement_destroy<T> dtor;
|
||||
return this->priv_generic_named_destroy<char>
|
||||
(typeid(T).name(), m_header.m_unique_index, dtor, is_intrusive_t());
|
||||
}
|
||||
|
||||
//!Destroys the named object with
|
||||
//!the given name. Returns false if that object can't be found.
|
||||
template <class T>
|
||||
bool destroy(const CharType *name)
|
||||
{
|
||||
ipcdetail::placement_destroy<T> dtor;
|
||||
return this->priv_generic_named_destroy<CharType>
|
||||
(name, m_header.m_named_index, dtor, is_intrusive_t());
|
||||
if(name.is_unique()){
|
||||
return this->priv_generic_named_destroy<char>
|
||||
( typeid(T).name(), m_header.m_unique_index , dtor, is_intrusive_t());
|
||||
}
|
||||
else{
|
||||
return this->priv_generic_named_destroy<CharType>
|
||||
( name.get(), m_header.m_named_index, dtor, is_intrusive_t());
|
||||
}
|
||||
}
|
||||
|
||||
//!Destroys an anonymous, unique or named object
|
||||
//!using it's address
|
||||
//!using its address
|
||||
template <class T>
|
||||
void destroy_ptr(const T *p)
|
||||
{
|
||||
@@ -628,7 +622,7 @@ class segment_manager
|
||||
//!Obtains the minimum size needed by the
|
||||
//!segment manager
|
||||
static size_type get_min_size()
|
||||
{ return Base::get_min_size(priv_get_reserved_bytes()); }
|
||||
{ return segment_manager_base_t::get_min_size(priv_get_reserved_bytes()); }
|
||||
|
||||
//!Returns a constant iterator to the beginning of the information about
|
||||
//!the named allocations performed in this segment manager
|
||||
@@ -685,8 +679,8 @@ class segment_manager
|
||||
typedef boost::interprocess::deleter<T, segment_manager> type;
|
||||
};
|
||||
|
||||
//!Returns an instance of the default allocator for type T
|
||||
//!initialized that allocates memory from this segment manager.
|
||||
//!Returns an instance of the default deleter for type T
|
||||
//!that will delete an object constructed in this segment manager.
|
||||
template<class T>
|
||||
typename deleter<T>::type
|
||||
get_deleter()
|
||||
@@ -742,11 +736,8 @@ class segment_manager
|
||||
return std::pair<T*, size_type>(static_cast<T*>(ret), size);
|
||||
}
|
||||
|
||||
void *priv_generic_construct(const CharType *name,
|
||||
size_type num,
|
||||
bool try2find,
|
||||
bool dothrow,
|
||||
ipcdetail::in_place_interface &table)
|
||||
void *priv_generic_construct
|
||||
(const CharType *name, size_type num, bool try2find, bool dothrow, ipcdetail::in_place_interface &table)
|
||||
{
|
||||
void *ret;
|
||||
//Security overflow check
|
||||
@@ -800,7 +791,7 @@ class segment_manager
|
||||
static const CharType *priv_get_instance_name(block_header_t *ctrl_data)
|
||||
{
|
||||
boost::interprocess::allocation_type type = ctrl_data->alloc_type();
|
||||
if(type != named_type){
|
||||
if(type == anonymous_type){
|
||||
BOOST_ASSERT((type == anonymous_type && ctrl_data->m_num_char == 0) ||
|
||||
(type == unique_type && ctrl_data->m_num_char != 0) );
|
||||
return 0;
|
||||
@@ -832,8 +823,8 @@ class segment_manager
|
||||
static size_type priv_get_reserved_bytes()
|
||||
{
|
||||
//Get the number of bytes until the end of (*this)
|
||||
//beginning in the end of the Base base.
|
||||
return sizeof(segment_manager) - sizeof(Base);
|
||||
//beginning in the end of the segment_manager_base_t base.
|
||||
return sizeof(segment_manager) - sizeof(segment_manager_base_t);
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
@@ -841,9 +832,7 @@ class segment_manager
|
||||
(const CharT* name,
|
||||
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
|
||||
ipcdetail::in_place_interface &table,
|
||||
size_type &length,
|
||||
ipcdetail::true_ is_intrusive,
|
||||
bool use_lock)
|
||||
size_type &length, ipcdetail::true_ is_intrusive, bool use_lock)
|
||||
{
|
||||
(void)is_intrusive;
|
||||
typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
|
||||
@@ -880,9 +869,7 @@ class segment_manager
|
||||
(const CharT* name,
|
||||
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
|
||||
ipcdetail::in_place_interface &table,
|
||||
size_type &length,
|
||||
ipcdetail::false_ is_intrusive,
|
||||
bool use_lock)
|
||||
size_type &length, ipcdetail::false_ is_intrusive, bool use_lock)
|
||||
{
|
||||
(void)is_intrusive;
|
||||
typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
|
||||
@@ -918,8 +905,7 @@ class segment_manager
|
||||
bool priv_generic_named_destroy
|
||||
(block_header_t *block_header,
|
||||
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
|
||||
ipcdetail::in_place_interface &table,
|
||||
ipcdetail::true_ is_node_index)
|
||||
ipcdetail::in_place_interface &table, ipcdetail::true_ is_node_index)
|
||||
{
|
||||
(void)is_node_index;
|
||||
typedef typename IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> >::iterator index_it;
|
||||
@@ -943,8 +929,7 @@ class segment_manager
|
||||
template <class CharT>
|
||||
bool priv_generic_named_destroy(const CharT *name,
|
||||
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
|
||||
ipcdetail::in_place_interface &table,
|
||||
ipcdetail::true_ is_intrusive_index)
|
||||
ipcdetail::in_place_interface &table, ipcdetail::true_ is_intrusive_index)
|
||||
{
|
||||
(void)is_intrusive_index;
|
||||
typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
|
||||
@@ -1060,21 +1045,17 @@ class segment_manager
|
||||
}
|
||||
|
||||
//Call destructors and free memory
|
||||
std::size_t destroyed;
|
||||
std::size_t destroyed;
|
||||
table.destroy_n(values, num, destroyed);
|
||||
this->deallocate(memory);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class CharT>
|
||||
void * priv_generic_named_construct(unsigned char type,
|
||||
const CharT *name,
|
||||
size_type num,
|
||||
bool try2find,
|
||||
bool dothrow,
|
||||
ipcdetail::in_place_interface &table,
|
||||
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
|
||||
ipcdetail::true_ is_intrusive)
|
||||
void * priv_generic_named_construct
|
||||
(unsigned char type, const CharT *name, size_type num, bool try2find,
|
||||
bool dothrow, ipcdetail::in_place_interface &table,
|
||||
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index, ipcdetail::true_ is_intrusive)
|
||||
{
|
||||
(void)is_intrusive;
|
||||
std::size_t namelen = std::char_traits<CharT>::length(name);
|
||||
@@ -1196,14 +1177,10 @@ class segment_manager
|
||||
//!Generic named new function for
|
||||
//!named functions
|
||||
template<class CharT>
|
||||
void * priv_generic_named_construct(unsigned char type,
|
||||
const CharT *name,
|
||||
size_type num,
|
||||
bool try2find,
|
||||
bool dothrow,
|
||||
ipcdetail::in_place_interface &table,
|
||||
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
|
||||
ipcdetail::false_ is_intrusive)
|
||||
void * priv_generic_named_construct
|
||||
(unsigned char type, const CharT *name, size_type num, bool try2find, bool dothrow,
|
||||
ipcdetail::in_place_interface &table,
|
||||
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index, ipcdetail::false_ is_intrusive)
|
||||
{
|
||||
(void)is_intrusive;
|
||||
std::size_t namelen = std::char_traits<CharT>::length(name);
|
||||
@@ -1346,9 +1323,9 @@ class segment_manager
|
||||
named_index_t m_named_index;
|
||||
unique_index_t m_unique_index;
|
||||
|
||||
header_t(Base *restricted_segment_mngr)
|
||||
: m_named_index (restricted_segment_mngr)
|
||||
, m_unique_index(restricted_segment_mngr)
|
||||
header_t(segment_manager_base_t *segment_mngr_base)
|
||||
: m_named_index (segment_mngr_base)
|
||||
, m_unique_index(segment_mngr_base)
|
||||
{}
|
||||
} m_header;
|
||||
|
||||
|
||||
@@ -483,6 +483,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boost_use_windows_h", "boos
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "segment_manager_test", "segment_manager_test.vcproj", "{56CE18C9-0000-0000-0000-000000000000}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -975,6 +979,10 @@ Global
|
||||
{518CE8C3-6512-FA75-46EF-B917A3A116D1}.Debug.Build.0 = Debug|Win32
|
||||
{518CE8C3-6512-FA75-46EF-B917A3A116D1}.Release.ActiveCfg = Release|Win32
|
||||
{518CE8C3-6512-FA75-46EF-B917A3A116D1}.Release.Build.0 = Release|Win32
|
||||
{56CE18C9-0000-0000-0000-000000000000}.Debug.ActiveCfg = Debug|Win32
|
||||
{56CE18C9-0000-0000-0000-000000000000}.Debug.Build.0 = Debug|Win32
|
||||
{56CE18C9-0000-0000-0000-000000000000}.Release.ActiveCfg = Release|Win32
|
||||
{56CE18C9-0000-0000-0000-000000000000}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
||||
138
proj/vc7ide/segment_manager_test.vcproj
Normal file
138
proj/vc7ide/segment_manager_test.vcproj
Normal file
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="segment_manager_test"
|
||||
ProjectGUID="{56CE18C9-0000-0000-0000-000000000000}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/segment_manager_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/segment_manager_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/segment_manager_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/segment_manager_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/segment_manager_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{47FC4F21-A627-7641-06A6-A22AD322A75F}">
|
||||
<File
|
||||
RelativePath="..\..\test\segment_manager_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{33897750-B034-B78B-89BD-E25F1F9B2E6E}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
457
test/segment_manager_test.cpp
Normal file
457
test/segment_manager_test.cpp
Normal file
@@ -0,0 +1,457 @@
|
||||
#include <boost/interprocess/indexes/flat_map_index.hpp>
|
||||
#include <boost/interprocess/indexes/map_index.hpp>
|
||||
#include <boost/interprocess/indexes/null_index.hpp>
|
||||
#include <boost/interprocess/indexes/unordered_map_index.hpp>
|
||||
#include <boost/interprocess/indexes/iset_index.hpp>
|
||||
#include <boost/interprocess/indexes/iunordered_set_index.hpp>
|
||||
|
||||
#include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
|
||||
#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
|
||||
#include <boost/interprocess/mapped_region.hpp>
|
||||
#include <boost/interprocess/segment_manager.hpp>
|
||||
#include <boost/interprocess/shared_memory_object.hpp>
|
||||
#include <boost/interprocess/sync/mutex_family.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include "get_process_id_name.hpp"
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
#include <cstring>
|
||||
|
||||
using namespace boost::interprocess;
|
||||
|
||||
template <class SegmentManager>
|
||||
struct atomic_func_test
|
||||
{
|
||||
SegmentManager &rsm;
|
||||
int *object;
|
||||
|
||||
atomic_func_test(SegmentManager &sm)
|
||||
: rsm(sm), object()
|
||||
{}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
object = rsm.template find<int>("atomic_func_find_object").first;
|
||||
}
|
||||
};
|
||||
|
||||
template <class SegmentManager>
|
||||
bool test_segment_manager()
|
||||
{
|
||||
typedef typename SegmentManager::size_type size_type;
|
||||
const unsigned int ShmSizeSize = 1024*64u;
|
||||
std::string shmname(test::get_process_id_name());
|
||||
|
||||
shared_memory_object::remove(shmname.c_str());
|
||||
shared_memory_object sh_mem( create_only, shmname.c_str(), read_write );
|
||||
sh_mem.truncate( ShmSizeSize );
|
||||
mapped_region mapping( sh_mem, read_write );
|
||||
|
||||
SegmentManager* seg_mgr = new( mapping.get_address() ) SegmentManager( ShmSizeSize );
|
||||
std::size_t free_mem_before = seg_mgr->get_free_memory();
|
||||
std::size_t size_before = seg_mgr->get_size();
|
||||
|
||||
if(size_before != ShmSizeSize)
|
||||
return false;
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
if(seg_mgr->get_min_size() >= ShmSizeSize)
|
||||
return false;
|
||||
|
||||
{//test get_free_memory() / allocate()/deallocate()
|
||||
const size_type Size = ShmSizeSize/2;
|
||||
void *mem = seg_mgr->allocate(Size+1);
|
||||
const size_type free_mem = seg_mgr->get_free_memory();
|
||||
if(free_mem >= Size)
|
||||
return false;
|
||||
if(seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
const size_type Size2 = free_mem/2;
|
||||
void *mem2 = seg_mgr->allocate(size_type(Size2+1), std::nothrow);
|
||||
if(seg_mgr->get_free_memory() >= Size2)
|
||||
return false;
|
||||
if(seg_mgr->size(mem) < (Size+1))
|
||||
return false;
|
||||
if(seg_mgr->size(mem2) < (Size2+1))
|
||||
return false;
|
||||
seg_mgr->deallocate(mem);
|
||||
seg_mgr->deallocate(mem2);
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
try{ seg_mgr->allocate(ShmSizeSize*2); }catch(interprocess_exception&){}
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
if(seg_mgr->allocate(ShmSizeSize*2, std::nothrow))
|
||||
return false;
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
}
|
||||
{//test allocate_aligned
|
||||
const std::size_t Alignment = 128u;
|
||||
void *mem = seg_mgr->allocate_aligned(ShmSizeSize/4, Alignment);
|
||||
if(seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
std::size_t offset = static_cast<std::size_t>
|
||||
(static_cast<const char *>(mem) - static_cast<const char *>(mapping.get_address()));
|
||||
if(offset & (Alignment-1))
|
||||
return false;
|
||||
void *mem2 = seg_mgr->allocate_aligned(ShmSizeSize/4, Alignment, std::nothrow);
|
||||
std::size_t offset2 = static_cast<std::size_t>
|
||||
(static_cast<const char *>(mem2) - static_cast<const char *>(mapping.get_address()));
|
||||
if(offset2 & (Alignment-1))
|
||||
return false;
|
||||
seg_mgr->deallocate(mem);
|
||||
seg_mgr->deallocate(mem2);
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
try{ seg_mgr->allocate_aligned(ShmSizeSize*2, Alignment); }catch(interprocess_exception&){}
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
if(seg_mgr->allocate_aligned(ShmSizeSize*2, Alignment, std::nothrow))
|
||||
return false;
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
}
|
||||
{//test shrink_to_fit
|
||||
|
||||
seg_mgr->shrink_to_fit();
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
std::size_t empty_shrunk_size = seg_mgr->get_size();
|
||||
std::size_t empty_shrunk_free_mem = seg_mgr->get_free_memory();
|
||||
if(empty_shrunk_size >= size_before)
|
||||
return false;
|
||||
if(empty_shrunk_free_mem >= size_before)
|
||||
return false;
|
||||
seg_mgr->grow(size_type(size_before - empty_shrunk_size));
|
||||
if(seg_mgr->get_size() != size_before)
|
||||
return false;
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
}
|
||||
{//test zero_free_memory
|
||||
const size_type Size(ShmSizeSize/2+1), Size2(ShmSizeSize/8);
|
||||
void *mem = seg_mgr->allocate(Size);
|
||||
void *mem2 = seg_mgr->allocate(Size2);
|
||||
//Mark memory to non-zero
|
||||
std::memset(mem, 0xFF, Size);
|
||||
std::memset(mem2, 0xFF, Size2);
|
||||
static unsigned char zerobuf[Size];
|
||||
//Deallocate and check still non-zero
|
||||
seg_mgr->deallocate(mem);
|
||||
seg_mgr->deallocate(mem2);
|
||||
if(!std::memcmp(mem, zerobuf, Size))
|
||||
return false;
|
||||
if(!std::memcmp(mem2, zerobuf, Size2))
|
||||
return false;
|
||||
//zero_free_memory and check it's zeroed
|
||||
seg_mgr->zero_free_memory();
|
||||
//TODO: some parts are not zeroed because they are used
|
||||
//as internal metadata, find a way to test this
|
||||
//if(std::memcmp(mem, zerobuf, Size))
|
||||
//return false;
|
||||
//if(std::memcmp(mem2, zerobuf, Size2))
|
||||
//return false;
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
}
|
||||
|
||||
{//test anonymous object
|
||||
int *int_object = seg_mgr->template construct<int>(anonymous_instance)();
|
||||
if(1 != seg_mgr->get_instance_length(int_object))
|
||||
return false;
|
||||
if(anonymous_type != seg_mgr->get_instance_type(int_object))
|
||||
return false;
|
||||
if(seg_mgr->get_instance_name(int_object))
|
||||
return false;
|
||||
seg_mgr->destroy_ptr(int_object);
|
||||
int const int_array_values[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
int *int_array = seg_mgr->template construct_it<int>(anonymous_instance, std::nothrow)[10](&int_array_values[0]);
|
||||
if(10 != seg_mgr->get_instance_length(int_object))
|
||||
return false;
|
||||
if(anonymous_type != seg_mgr->get_instance_type(int_array))
|
||||
return false;
|
||||
if(seg_mgr->get_instance_name(int_array))
|
||||
return false;
|
||||
seg_mgr->destroy_ptr(int_array);
|
||||
try{ seg_mgr->template construct<int>(anonymous_instance)[ShmSizeSize](); }catch(interprocess_exception&){}
|
||||
if(seg_mgr->template construct<int>(anonymous_instance, std::nothrow)[ShmSizeSize]())
|
||||
try{ seg_mgr->template construct_it<int>(anonymous_instance)[ShmSizeSize](&int_array_values[0]); }catch(interprocess_exception&){}
|
||||
if(seg_mgr->template construct_it<int>(anonymous_instance, std::nothrow)[ShmSizeSize](&int_array_values[0]))
|
||||
return false;
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
}
|
||||
|
||||
{//test named object
|
||||
const char *const object1_name = "object1";
|
||||
const char *const object2_name = "object2";
|
||||
int const int_array_values[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
|
||||
for(std::size_t i = 0; i != 4; ++i){
|
||||
if(seg_mgr->template find<unsigned int>(object1_name).first)
|
||||
return false;
|
||||
//Single element construction
|
||||
unsigned int *uint_object = 0;
|
||||
switch(i){
|
||||
case 0:
|
||||
uint_object = seg_mgr->template construct<unsigned int>(object1_name)();
|
||||
break;
|
||||
case 1:
|
||||
uint_object = seg_mgr->template construct<unsigned int>(object1_name, std::nothrow)();
|
||||
break;
|
||||
case 2:
|
||||
uint_object = seg_mgr->template find_or_construct<unsigned int>(object1_name)();
|
||||
break;
|
||||
case 3:
|
||||
uint_object = seg_mgr->template find_or_construct<unsigned int>(object1_name, std::nothrow)();
|
||||
break;
|
||||
}
|
||||
std::pair<unsigned int*, std::size_t> find_ret = seg_mgr->template find<unsigned int>(object1_name);
|
||||
if(uint_object != find_ret.first)
|
||||
return false;
|
||||
if(1 != find_ret.second)
|
||||
return false;
|
||||
if(1 != seg_mgr->get_instance_length(uint_object))
|
||||
return false;
|
||||
if(named_type != seg_mgr->get_instance_type(uint_object))
|
||||
return false;
|
||||
if(std::strcmp(object1_name, seg_mgr->get_instance_name(uint_object)))
|
||||
return false;
|
||||
//Array construction
|
||||
if(seg_mgr->template find<int>(object2_name).first)
|
||||
return false;
|
||||
int *int_array = 0;
|
||||
switch(i){
|
||||
case 0:
|
||||
int_array = seg_mgr->template construct_it<int>(object2_name)[10](&int_array_values[0]);
|
||||
break;
|
||||
case 1:
|
||||
int_array = seg_mgr->template construct_it<int>(object2_name, std::nothrow)[10](&int_array_values[0]);
|
||||
break;
|
||||
case 2:
|
||||
int_array = seg_mgr->template find_or_construct_it<int>(object2_name)[10](&int_array_values[0]);
|
||||
break;
|
||||
case 3:
|
||||
int_array = seg_mgr->template find_or_construct_it<int>(object2_name, std::nothrow)[10](&int_array_values[0]);
|
||||
break;
|
||||
}
|
||||
std::pair<int*, std::size_t> find_ret2 = seg_mgr->template find<int>(object2_name);
|
||||
if(int_array != find_ret2.first)
|
||||
return false;
|
||||
if(10 != find_ret2.second)
|
||||
return false;
|
||||
if(10 != seg_mgr->get_instance_length(int_array))
|
||||
return false;
|
||||
if(named_type != seg_mgr->get_instance_type(int_array))
|
||||
return false;
|
||||
if(std::strcmp(object2_name, seg_mgr->get_instance_name(int_array)))
|
||||
return false;
|
||||
if(seg_mgr->get_num_named_objects() != 2)
|
||||
return false;
|
||||
typename SegmentManager::const_named_iterator nb(seg_mgr->named_begin());
|
||||
typename SegmentManager::const_named_iterator ne(seg_mgr->named_end());
|
||||
for(std::size_t i = 0, imax = seg_mgr->get_num_named_objects(); i != imax; ++i){ ++nb; }
|
||||
if(nb != ne)
|
||||
return false;
|
||||
seg_mgr->destroy_ptr(uint_object);
|
||||
seg_mgr->template destroy<int>(object2_name);
|
||||
}
|
||||
try{ seg_mgr->template construct<unsigned int>(object1_name)[ShmSizeSize](); }catch(interprocess_exception&){}
|
||||
if(seg_mgr->template construct<int>(object2_name, std::nothrow)[ShmSizeSize]())
|
||||
try{ seg_mgr->template construct_it<unsigned int>(object1_name)[ShmSizeSize](&int_array_values[0]); }catch(interprocess_exception&){}
|
||||
if(seg_mgr->template construct_it<int>(object2_name, std::nothrow)[ShmSizeSize](&int_array_values[0]))
|
||||
return false;
|
||||
seg_mgr->shrink_to_fit_indexes();
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
seg_mgr->reserve_named_objects(1);
|
||||
//In indexes with no capacity() memory won't be allocated so don't check anything was allocated.
|
||||
//if(seg_mgr->all_memory_deallocated()) return false;
|
||||
seg_mgr->shrink_to_fit_indexes();
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
}
|
||||
|
||||
{//test unique object
|
||||
int const int_array_values[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
|
||||
for(std::size_t i = 0; i != 4; ++i){
|
||||
if(seg_mgr->template find<unsigned int>(unique_instance).first)
|
||||
return false;
|
||||
//Single element construction
|
||||
unsigned int *uint_object = 0;
|
||||
switch(i){
|
||||
case 0:
|
||||
uint_object = seg_mgr->template construct<unsigned int>(unique_instance)();
|
||||
break;
|
||||
case 1:
|
||||
uint_object = seg_mgr->template construct<unsigned int>(unique_instance, std::nothrow)();
|
||||
break;
|
||||
case 2:
|
||||
uint_object = seg_mgr->template find_or_construct<unsigned int>(unique_instance)();
|
||||
break;
|
||||
case 3:
|
||||
uint_object = seg_mgr->template find_or_construct<unsigned int>(unique_instance, std::nothrow)();
|
||||
break;
|
||||
}
|
||||
std::pair<unsigned int*, std::size_t> find_ret = seg_mgr->template find<unsigned int>(unique_instance);
|
||||
if(uint_object != find_ret.first)
|
||||
return false;
|
||||
if(1 != find_ret.second)
|
||||
return false;
|
||||
if(1 != seg_mgr->get_instance_length(uint_object))
|
||||
return false;
|
||||
if(unique_type != seg_mgr->get_instance_type(uint_object))
|
||||
return false;
|
||||
if(std::strcmp(typeid(unsigned int).name(), seg_mgr->get_instance_name(uint_object)))
|
||||
return false;
|
||||
//Array construction
|
||||
if(seg_mgr->template find<int>(unique_instance).first)
|
||||
return false;
|
||||
int *int_array = 0;
|
||||
switch(i){
|
||||
case 0:
|
||||
int_array = seg_mgr->template construct_it<int>(unique_instance)[10](&int_array_values[0]);
|
||||
break;
|
||||
case 1:
|
||||
int_array = seg_mgr->template construct_it<int>(unique_instance, std::nothrow)[10](&int_array_values[0]);
|
||||
break;
|
||||
case 2:
|
||||
int_array = seg_mgr->template find_or_construct_it<int>(unique_instance)[10](&int_array_values[0]);
|
||||
break;
|
||||
case 3:
|
||||
int_array = seg_mgr->template find_or_construct_it<int>(unique_instance, std::nothrow)[10](&int_array_values[0]);
|
||||
break;
|
||||
}
|
||||
std::pair<int*, std::size_t> find_ret2 = seg_mgr->template find<int>(unique_instance);
|
||||
if(int_array != find_ret2.first)
|
||||
return false;
|
||||
if(10 != find_ret2.second)
|
||||
return false;
|
||||
if(10 != seg_mgr->get_instance_length(int_array))
|
||||
return false;
|
||||
if(unique_type != seg_mgr->get_instance_type(int_array))
|
||||
return false;
|
||||
if(std::strcmp(typeid(int).name(), seg_mgr->get_instance_name(int_array)))
|
||||
return false;
|
||||
if(seg_mgr->get_num_unique_objects() != 2)
|
||||
return false;
|
||||
typename SegmentManager::const_unique_iterator nb(seg_mgr->unique_begin());
|
||||
typename SegmentManager::const_unique_iterator ne(seg_mgr->unique_end());
|
||||
for(std::size_t i = 0, imax = seg_mgr->get_num_unique_objects(); i != imax; ++i){ ++nb; }
|
||||
if(nb != ne)
|
||||
return false;
|
||||
seg_mgr->destroy_ptr(uint_object);
|
||||
seg_mgr->template destroy<int>(unique_instance);
|
||||
}
|
||||
try{ seg_mgr->template construct<unsigned int>(unique_instance)[ShmSizeSize](); }catch(interprocess_exception&){}
|
||||
if(seg_mgr->template construct<int>(unique_instance, std::nothrow)[ShmSizeSize]())
|
||||
try{ seg_mgr->template construct_it<unsigned int>(unique_instance)[ShmSizeSize](&int_array_values[0]); }catch(interprocess_exception&){}
|
||||
if(seg_mgr->template construct_it<int>(unique_instance, std::nothrow)[ShmSizeSize](&int_array_values[0]))
|
||||
return false;
|
||||
seg_mgr->shrink_to_fit_indexes();
|
||||
if(seg_mgr->get_free_memory() != free_mem_before)
|
||||
return false;
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
seg_mgr->reserve_unique_objects(1);
|
||||
//In indexes with no capacity() memory won't be allocated so don't check anything was allocated.
|
||||
//if(seg_mgr->all_memory_deallocated()) return false;
|
||||
seg_mgr->shrink_to_fit_indexes();
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
}
|
||||
{//test allocator/deleter
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
typedef typename SegmentManager::template allocator<float>::type allocator_t;
|
||||
typedef typename SegmentManager::template deleter<float>::type deleter_t;
|
||||
|
||||
allocator_t alloc(seg_mgr->template get_allocator<float>());
|
||||
deleter_t delet(seg_mgr->template get_deleter<float>());
|
||||
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
offset_ptr<float> f = alloc.allocate(50);
|
||||
if(seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
alloc.deallocate(f, 50);
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
}
|
||||
{//test allocator/deleter
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
int *int_object = seg_mgr->template construct<int>("atomic_func_find_object")();
|
||||
atomic_func_test<SegmentManager> func(*seg_mgr);
|
||||
seg_mgr->atomic_func(func);
|
||||
if(int_object != func.object)
|
||||
return 1;
|
||||
seg_mgr->destroy_ptr(int_object);
|
||||
seg_mgr->shrink_to_fit_indexes();
|
||||
if(!seg_mgr->all_memory_deallocated())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class MemoryAlgorithm>
|
||||
bool test_each_algo()
|
||||
{
|
||||
{
|
||||
typedef segment_manager< char, MemoryAlgorithm, flat_map_index > segment_manager_t;
|
||||
if(!test_segment_manager<segment_manager_t>())
|
||||
return false;
|
||||
}
|
||||
{
|
||||
typedef segment_manager< char, MemoryAlgorithm, map_index > segment_manager_t;
|
||||
if(!test_segment_manager<segment_manager_t>())
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
{
|
||||
typedef segment_manager< char, MemoryAlgorithm, null_index > segment_manager_t;
|
||||
if(!test_segment_manager<segment_manager_t>())
|
||||
return false;
|
||||
}*/
|
||||
/*
|
||||
{
|
||||
typedef segment_manager< char, MemoryAlgorithm, unordered_map_index > segment_manager_t;
|
||||
if(!test_segment_manager<segment_manager_t>())
|
||||
return false;
|
||||
}*/
|
||||
{
|
||||
typedef segment_manager< char, MemoryAlgorithm, iset_index > segment_manager_t;
|
||||
if(!test_segment_manager<segment_manager_t>())
|
||||
return false;
|
||||
}
|
||||
{
|
||||
typedef segment_manager< char, MemoryAlgorithm, iunordered_set_index > segment_manager_t;
|
||||
if(!test_segment_manager<segment_manager_t>())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
if(!test_each_algo< simple_seq_fit< null_mutex_family > >())
|
||||
return 1;
|
||||
if(!test_each_algo< rbtree_best_fit< null_mutex_family > >())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user