Intrusive:

*  Added `linear<>` and `cache_last<>` options to singly linked lists.
*  Added `optimize_multikey<>` option to unordered container hooks.
*  Optimized unordered containers when `store_hash` option is used in the hook.
*  Implementation changed to be exception agnostic so that it can be used
   in environments without exceptions.
*  Added `container_from_iterator` function to tree-based containers.

Interprocess:

*  Added anonymous shared memory for UNIX systems.
*  Fixed file lock compilation errors

[SVN r44819]
This commit is contained in:
Ion Gaztañaga
2008-04-27 15:03:06 +00:00
parent 15990aea8c
commit 3af7cdba54
60 changed files with 2472 additions and 669 deletions

View File

@@ -58,6 +58,15 @@ separate compilation. However, the subset used by [*Boost.Interprocess] does
not need any separate compilation so the user can define `BOOST_DATE_TIME_NO_LIB`
to avoid Boost from trying to automatically link the [*Boost.DateTime].
In POSIX systems, [*Boost.Interprocess] uses pthread system calls to implement
classes like mutexes, condition variables, etc... In some operating systems,
these POSIX calls are implemented in separate libraries that are not automatically
linked by the compiler. For example, in some Linux systems POSIX pthread functions
are implemented in `librt.a` library, so you might need to add that library
when linking an executable or shared library that uses [*Boost.Interprocess].
If you obtain linking errors related to those pthread functions, please revise
your system's documentation to know which library implements them.
[endsect]
[section:tested_compilers Tested compilers]
@@ -551,6 +560,30 @@ behavior as the standard C (stdio.h) `int remove(const char *path)` function.
[endsect]
[section:anonymous_shared_memory Anonymous shared memory for UNIX systems]
Creating a shared memory segment and mapping it can be a bit tedious when several
processes are involved. When processes are related via `fork()` operating system
call in UNIX sytems a simpler method is available using anonymous shared memory.
This feature has been implemented in UNIX systems mapping the device `\dev\zero` or
just using the `MAP_ANONYMOUS` in a POSIX conformant `mmap` system call.
This feature is wrapped in [*Boost.Interprocess] using the `anonymous_shared_memory()`
function, which returns a `mapped_region` object holding an anonymous shared memory
segment that can be shared by related processes.
Here's is an example:
[import ../example/doc_anonymous_shared_memory.cpp]
[doc_anonymous_shared_memory]
Once the segment is created, a `fork()` call can
be used so that `region` is used to communicate two related processes.
[endsect]
[section:windows_shared_memory Native windows shared memory]
Windows operating system also offers shared memory, but the lifetime of this
@@ -1298,7 +1331,7 @@ All the mutex types from [*Boost.Interprocess] implement the following operation
[blurb ['[*void lock()]]]
[*Effects:]
The calling thread tries to obtain ownership of the mutex, and if another thread has ownership of the mutex, it waits until it can obtain the ownership. If a thread takes ownership of the mutex the mutex must be unlocked by the same mutex. If the mutex supports recursive locking, the mutex must be unlocked the same number of times it is locked.
The calling thread tries to obtain ownership of the mutex, and if another thread has ownership of the mutex, it waits until it can obtain the ownership. If a thread takes ownership of the mutex the mutex must be unlocked by the same thread. If the mutex supports recursive locking, the mutex must be unlocked the same number of times it is locked.
[*Throws:] *interprocess_exception* on error.
@@ -4935,6 +4968,41 @@ Boost.Interprocess containers:
[endsect]
[section:additional_containers Boost containers compatible with Boost.Interprocess]
As mentioned, container developers might need to change their implementation to make them
compatible with Boost.Interprocess, because implementation usually ignore allocators with
smart pointers. Hopefully several Boost containers are compatible with [*Interprocess].
[section:unordered Boost unordered containers]
[*Boost.Unordered] containers are compatible with Interprocess, so programmers can store
hash containers in shared memory and memory mapped files. Here's an small example storing
`unordered_map` in shared memory:
[import ../example/doc_unordered_map.cpp]
[doc_unordered_map]
[endsect]
[section:multi_index Boost.MultiIndex containers]
The widely used [*Boost.MultiIndex] library is compatible with [*Boost.Interprocess] so
we can construct pretty good databases in shared memory. Constructing databases in shared
memory is a bit tougher than in normal memory, usually because those databases contain strings
and those strings need to be placed in shared memory. Shared memory strings require
an allocator in their constructors so this usually makes object insertion a bit more
complicated.
Here's is an example that shows how to put a multi index container in shared memory:
[import ../example/doc_multi_index.cpp]
[doc_multi_index]
[endsect]
[endsect]
[section:memory_algorithms Memory allocation algorithms]
[section:simple_seq_fit simple_seq_fit: A simple shared memory management algorithm]
@@ -6262,7 +6330,7 @@ will manage the index. `segment_manager` will define interesting internal types
For example, the index type `flat_map_index` based in `boost::interprocess::flat_map`
is just defined as:
[import ../../../boost/interprocess/indexes/flat_map_index.hpp]
[import ../../boost/interprocess/indexes/flat_map_index.hpp]
[flat_map_index]
@@ -6385,6 +6453,12 @@ warranty.
[section:release_notes Release Notes]
[section:release_notes_boost_1_36_00 Boost 1.36 Release]
* Added anonymous shared memory for UNIX systems.
[endsect]
[section:release_notes_boost_1_35_00 Boost 1.35 Release]
* Added auxiliary utilities to ease the definition and construction of
@@ -6654,20 +6728,6 @@ But the work to implement PF_UNIX-like sockets and doors would be huge
[endsect]
[section:future_containers Unordered associative containers and other containers]
We should be able to construct boost::unordered_xxx family in managed memory segments,
so that there is no code duplication in boost. So [*Boost.Interprocess] should cooperate
with boost container developers instead of duplicating effort writing it's own containers.
A very interesting project is making [*boost::multi_index] compatible with
[*Boost.Interprocess] ready for shared memory. This could be a good basis for memory
mapped data-bases. The work to achieve this, however, can be huge. It would be
interesting a collaboration with [*Intrusive] library to achieve shared memory
intrusive containers.
[endsect]
[endsect]
[endsect]

View File

@@ -0,0 +1,36 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
//[doc_anonymous_shared_memory
#include <boost/interprocess/anonymous_shared_memory.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
#include <cstring>
int main ()
{
using namespace boost::interprocess;
try{
//Create an anonymous shared memory segment with size 1000
mapped_region region(anonymous_shared_memory(1000));
//Write all the memory to 1
std::memset(region.get_address(), 1, region.get_size());
//The segment is unmapped when "region" goes out of scope
}
catch(interprocess_exception &ex){
std::cout << ex.what() << std::endl;
return 1;
}
return 0;
}
//]
#include <boost/interprocess/detail/config_end.hpp>

View File

@@ -0,0 +1,91 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
//[doc_multi_index
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
using namespace boost::interprocess;
namespace bmi = boost::multi_index;
typedef managed_shared_memory::allocator<char>::type char_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator>shm_string;
//Data to insert in shared memory
struct employee
{
int id;
int age;
shm_string name;
employee( int id_
, int age_
, const char *name_
, const char_allocator &a)
: id(id_), age(age_), name(name_, a)
{}
};
//Tags
struct id{};
struct age{};
struct name{};
// Define a multi_index_container of employees with following indices:
// - a unique index sorted by employee::int,
// - a non-unique index sorted by employee::name,
// - a non-unique index sorted by employee::age.
typedef bmi::multi_index_container<
employee,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
bmi::ordered_non_unique<
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
managed_shared_memory::allocator<employee>::type
> employee_set;
int main ()
{
//Erase previous shared memory with the name
shared_memory_object::remove("MySharedMemory");
try{
//Create shared memory
managed_shared_memory segment(create_only,"MySharedMemory", 65536);
//Construct the multi_index in shared memory
employee_set *es = segment.construct<employee_set>
("My MultiIndex Container") //Container's name in shared memory
( employee_set::ctor_args_list()
, segment.get_allocator<employee>()); //Ctor parameters
//Now insert elements
char_allocator ca(segment.get_allocator<char>());
es->insert(employee(0,31, "Joe", ca));
es->insert(employee(1,27, "Robert", ca));
es->insert(employee(2,40, "John", ca));
}
catch(...){
shared_memory_object::remove("MySharedMemory");
throw;
}
shared_memory_object::remove("MySharedMemory");
return 0;
}
//]
#include <boost/interprocess/detail/config_end.hpp>

View File

@@ -0,0 +1,66 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
//[doc_unordered_map
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/unordered_map.hpp> //boost::unordered_map
#include <functional> //std::equal_to
#include <boost/functional/hash.hpp> //boost::hash
int main ()
{
using namespace boost::interprocess;
//Erase previous shared memory with the name
shared_memory_object::remove("MySharedMemory");
try{
//Create shared memory
managed_shared_memory segment(create_only ,"MySharedMemory" ,65536);
//Note that unordered_map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
//so the allocator must allocate that pair.
typedef int KeyType;
typedef float MappedType;
typedef std::pair<const int, float> ValueType;
//Typedef the allocator
typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator;
//Alias an unordered_map of ints that uses the previous STL-like allocator.
typedef boost::unordered_map
< KeyType , MappedType
, boost::hash<KeyType> ,std::equal_to<KeyType>
, ShmemAllocator>
MyHashMap;
//Construct a shared memory hash map.
//Note that the first parameter is the initial bucket count and
//after that, the hash function, the equality function and the allocator
MyHashMap *myhashmap = segment.construct<MyHashMap>("MyHashMap") //object name
( 3, boost::hash<int>(), std::equal_to<int>() //
, segment.get_allocator<ValueType>()); //allocator instance
//Insert data in the hash map
for(int i = 0; i < 100; ++i){
myhashmap->insert(ValueType(i, (float)i));
}
}
catch(...){
shared_memory_object::remove("MySharedMemory");
throw;
}
shared_memory_object::remove("MySharedMemory");
return 0;
}
//]
#include <boost/interprocess/detail/config_end.hpp>

View File

@@ -26,6 +26,7 @@
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
@@ -39,7 +40,7 @@ namespace interprocess {
/// @cond
namespace detail{
/*
template < unsigned int Version
, class T
, class SegmentManager
@@ -61,8 +62,9 @@ class adaptive_pool_base
typedef SegmentManager segment_manager;
typedef adaptive_pool_base
<Version, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> self_t;
static const std::size_t SizeOfT = sizeof(detail::if_c<detail::is_same<T, void>::value, int, T>::type);
typedef detail::shared_adaptive_node_pool
< SegmentManager, sizeof(T), NodesPerChunk, MaxFreeChunks, OverheadPercent> node_pool_t;
< SegmentManager, SizeOfT, NodesPerChunk, MaxFreeChunks, OverheadPercent> node_pool_t;
typedef typename detail::
pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
@@ -157,19 +159,153 @@ class adaptive_pool_base
node_pool_ptr mp_node_pool;
/// @endcond
};
*/
template < unsigned int Version
, class T
, class SegmentManager
, std::size_t NodesPerChunk
, std::size_t MaxFreeChunks
, unsigned char OverheadPercent
>
class adaptive_pool_base
: public node_pool_allocation_impl
< adaptive_pool_base
< Version, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent>
, Version
, T
, SegmentManager
>
{
public:
typedef typename SegmentManager::void_pointer void_pointer;
typedef SegmentManager segment_manager;
typedef adaptive_pool_base
<Version, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> self_t;
/// @cond
template <int dummy>
struct node_pool
{
typedef detail::shared_adaptive_node_pool
< SegmentManager, sizeof(T), NodesPerChunk, MaxFreeChunks, OverheadPercent> type;
static type *get(void *p)
{ return static_cast<type*>(p); }
};
/// @endcond
BOOST_STATIC_ASSERT((Version <=2));
public:
//-------
typedef typename detail::
pointer_to_other<void_pointer, T>::type pointer;
typedef typename detail::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
typedef typename detail::add_reference
<value_type>::type reference;
typedef typename detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef detail::version_type<adaptive_pool_base, Version> version;
typedef transform_iterator
< typename SegmentManager::
multiallocation_iterator
, detail::cast_functor <T> > multiallocation_iterator;
typedef typename SegmentManager::
multiallocation_chain multiallocation_chain;
//!Obtains adaptive_pool_base from
//!adaptive_pool_base
template<class T2>
struct rebind
{
typedef adaptive_pool_base<Version, T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
};
/// @cond
private:
//!Not assignable from related adaptive_pool_base
template<unsigned int Version2, class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char O2>
adaptive_pool_base& operator=
(const adaptive_pool_base<Version2, T2, SegmentManager2, N2, F2, O2>&);
/// @endcond
public:
//!Constructor from a segment manager. If not present, constructs a node
//!pool. Increments the reference count of the associated node pool.
//!Can throw boost::interprocess::bad_alloc
adaptive_pool_base(segment_manager *segment_mngr)
: mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
//!Copy constructor from other adaptive_pool_base. Increments the reference
//!count of the associated node pool. Never throws
adaptive_pool_base(const adaptive_pool_base &other)
: mp_node_pool(other.get_node_pool())
{
node_pool<0>::get(detail::get_pointer(mp_node_pool))->inc_ref_count();
}
//!Assignment from other adaptive_pool_base
adaptive_pool_base& operator=(const adaptive_pool_base &other)
{
adaptive_pool_base c(other);
swap(*this, c);
return *this;
}
//!Copy constructor from related adaptive_pool_base. If not present, constructs
//!a node pool. Increments the reference count of the associated node pool.
//!Can throw boost::interprocess::bad_alloc
template<class T2>
adaptive_pool_base
(const adaptive_pool_base<Version, T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
: mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
//!Destructor, removes node_pool_t from memory
//!if its reference count reaches to zero. Never throws
~adaptive_pool_base()
{ detail::destroy_node_pool_if_last_link(node_pool<0>::get(detail::get_pointer(mp_node_pool))); }
//!Returns a pointer to the node pool.
//!Never throws
void* get_node_pool() const
{ return detail::get_pointer(mp_node_pool); }
//!Returns the segment manager.
//!Never throws
segment_manager* get_segment_manager()const
{ return node_pool<0>::get(detail::get_pointer(mp_node_pool))->get_segment_manager(); }
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different memory segment, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
/// @cond
private:
void_pointer mp_node_pool;
/// @endcond
};
//!Equality test for same type
//!of adaptive_pool_base
template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
bool operator==(const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc1,
const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc2)
template<unsigned int V, class T, class S, std::size_t NPC, std::size_t F, unsigned char OP> inline
bool operator==(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc2)
{ return alloc1.get_node_pool() == alloc2.get_node_pool(); }
//!Inequality test for same type
//!of adaptive_pool_base
template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
bool operator!=(const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc1,
const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc2)
template<unsigned int V, class T, class S, std::size_t NPC, std::size_t F, unsigned char OP> inline
bool operator!=(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc2)
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); }
template < class T
@@ -299,7 +435,7 @@ class adaptive_pool
//!Not assignable from
//!other adaptive_pool
adaptive_pool& operator=(const adaptive_pool&);
//adaptive_pool& operator=(const adaptive_pool&);
public:
//!Constructor from a segment manager. If not present, constructs a node
@@ -324,7 +460,7 @@ class adaptive_pool
//!Returns a pointer to the node pool.
//!Never throws
node_pool_t* get_node_pool() const;
void* get_node_pool() const;
//!Returns the segment manager.
//!Never throws
@@ -358,9 +494,9 @@ class adaptive_pool
//!Never throws
const_pointer address(const_reference value) const;
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr);
//!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
//!Destroys object. Throws if object's
//!destructor throws

View File

@@ -106,8 +106,6 @@ class allocator
<typename SegmentManager::
multiallocation_chain
, T> multiallocation_chain;
// typedef typename SegmentManager::
// multiallocation_chain multiallocation_chain;
/// @endcond
@@ -153,7 +151,7 @@ class allocator
//!Deallocates memory previously allocated.
//!Never throws
void deallocate(const pointer &ptr, size_type)
{ mp_mngr->deallocate(detail::get_pointer(ptr)); }
{ mp_mngr->deallocate((void*)detail::get_pointer(ptr)); }
//!Returns the number of elements that could be allocated.
//!Never throws
@@ -253,10 +251,15 @@ class allocator
const_pointer address(const_reference value) const
{ return const_pointer(boost::addressof(value)); }
//!Copy construct an object
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v)
{ new((void*)detail::get_pointer(ptr)) value_type(v); }
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr)
{ new(detail::get_pointer(ptr)) value_type; }
{ new((void*)detail::get_pointer(ptr)) value_type; }
//!Destroys object. Throws if object's
//!destructor throws

View File

@@ -119,7 +119,7 @@ class cached_adaptive_pool
< T
, detail::shared_adaptive_node_pool
< SegmentManager
, sizeof(T)
, sizeof(typename detail::if_c<detail::is_same<T, void>::value, int, T>::type)
, NodesPerChunk
, MaxFreeChunks
, OverheadPercent
@@ -252,9 +252,9 @@ class cached_adaptive_pool
//!Never throws
const_pointer address(const_reference value) const;
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr);
//!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
//!Destroys object. Throws if object's
//!destructor throws

View File

@@ -225,7 +225,7 @@ class cached_node_allocator
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr);
void construct(const pointer &ptr, const_reference v);
//!Destroys object. Throws if object's
//!destructor throws
@@ -302,15 +302,15 @@ class cached_node_allocator
//!Equality test for same type
//!of cached_node_allocator
template<class T, class S, std::size_t NodesPerChunk> inline
bool operator==(const cached_node_allocator<T, S, NodesPerChunk> &alloc1,
const cached_node_allocator<T, S, NodesPerChunk> &alloc2);
template<class T, class S, std::size_t NPC> inline
bool operator==(const cached_node_allocator<T, S, NPC> &alloc1,
const cached_node_allocator<T, S, NPC> &alloc2);
//!Inequality test for same type
//!of cached_node_allocator
template<class T, class S, std::size_t NodesPerChunk> inline
bool operator!=(const cached_node_allocator<T, S, NodesPerChunk> &alloc1,
const cached_node_allocator<T, S, NodesPerChunk> &alloc2);
template<class T, class S, std::size_t NPC> inline
bool operator!=(const cached_node_allocator<T, S, NPC> &alloc1,
const cached_node_allocator<T, S, NPC> &alloc2);
#endif

View File

@@ -49,7 +49,7 @@ class private_adaptive_node_pool_impl
private_adaptive_node_pool_impl &operator=(const private_adaptive_node_pool_impl &);
typedef typename SegmentManagerBase::void_pointer void_pointer;
static const std::size_t PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
public:
typedef typename node_slist<void_pointer>::node_t node_t;
typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
@@ -106,9 +106,11 @@ class private_adaptive_node_pool_impl
std::size_t candidate_power_of_2 =
upper_power_of_2(elements_per_subchunk*real_node_size + HdrOffsetSize);
bool overhead_satisfied = false;
//Now calculate the wors-case overhead for a subchunk
const std::size_t max_subchunk_overhead = HdrSize + PayloadPerAllocation;
while(!overhead_satisfied){
elements_per_subchunk = (candidate_power_of_2 - HdrOffsetSize)/real_node_size;
std::size_t overhead_size = candidate_power_of_2 - elements_per_subchunk*real_node_size;
elements_per_subchunk = (candidate_power_of_2 - max_subchunk_overhead)/real_node_size;
const std::size_t overhead_size = candidate_power_of_2 - elements_per_subchunk*real_node_size;
if(overhead_size*100/candidate_power_of_2 < overhead_percent){
overhead_satisfied = true;
}
@@ -121,14 +123,26 @@ class private_adaptive_node_pool_impl
static void calculate_num_subchunks
(std::size_t alignment, std::size_t real_node_size, std::size_t elements_per_chunk
,std::size_t &num_subchunks, std::size_t &real_num_node)
,std::size_t &num_subchunks, std::size_t &real_num_node, std::size_t overhead_percent)
{
std::size_t elements_per_subchunk = (alignment - HdrOffsetSize)/real_node_size;
std::size_t possible_num_subchunk = (elements_per_chunk - 1)/elements_per_subchunk + 1;
std::size_t hdr_subchunk_elements = (alignment - HdrSize - SegmentManagerBase::PayloadPerAllocation)/real_node_size;
std::size_t hdr_subchunk_elements = (alignment - HdrSize - PayloadPerAllocation)/real_node_size;
while(((possible_num_subchunk-1)*elements_per_subchunk + hdr_subchunk_elements) < elements_per_chunk){
++possible_num_subchunk;
}
elements_per_subchunk = (alignment - HdrOffsetSize)/real_node_size;
bool overhead_satisfied = false;
while(!overhead_satisfied){
const std::size_t total_data = (elements_per_subchunk*(possible_num_subchunk-1) + hdr_subchunk_elements)*real_node_size;
const std::size_t total_size = alignment*possible_num_subchunk;
if((total_size - total_data)*100/total_size < overhead_percent){
overhead_satisfied = true;
}
else{
++possible_num_subchunk;
}
}
num_subchunks = possible_num_subchunk;
real_num_node = (possible_num_subchunk-1)*elements_per_subchunk + hdr_subchunk_elements;
}
@@ -157,7 +171,7 @@ class private_adaptive_node_pool_impl
, m_chunk_multiset()
, m_totally_free_chunks(0)
{
calculate_num_subchunks(m_real_chunk_alignment, m_real_node_size, nodes_per_chunk, m_num_subchunks, m_real_num_node);
calculate_num_subchunks(m_real_chunk_alignment, m_real_node_size, nodes_per_chunk, m_num_subchunks, m_real_num_node, overhead_percent);
}
//!Destructor. Deallocates all allocated chunks. Never throws

View File

@@ -342,7 +342,12 @@ class array_allocation_impl
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr)
{ new(detail::get_pointer(ptr)) value_type; }
{ new((void*)detail::get_pointer(ptr)) value_type; }
//!Copy construct an object
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v)
{ new((void*)detail::get_pointer(ptr)) value_type(v); }
//!Destroys object. Throws if object's
//!destructor throws
@@ -386,36 +391,53 @@ class node_pool_allocation_impl
typedef typename SegmentManager::
multiallocation_chain multiallocation_chain;
template <int Dummy>
struct node_pool
{
typedef typename Derived::template node_pool<0>::type type;
static type *get(void *p)
{ return static_cast<type*>(p); }
};
public:
//!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0)
{
(void)hint;
typedef typename node_pool<0>::type node_pool_t;
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
if(count > this->max_size())
throw bad_alloc();
else if(Version == 1 && count == 1)
return pointer(static_cast<value_type*>(this->derived()->get_node_pool()->allocate_node()));
return pointer(static_cast<value_type*>
(pool->allocate_node()));
else
return pointer(static_cast<value_type*>
(this->derived()->get_node_pool()->get_segment_manager()->allocate(sizeof(T)*count)));
(pool->get_segment_manager()->allocate(sizeof(T)*count)));
}
//!Deallocate allocated memory. Never throws
void deallocate(const pointer &ptr, size_type count)
{
(void)count;
typedef typename node_pool<0>::type node_pool_t;
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
if(Version == 1 && count == 1)
this->derived()->get_node_pool()->deallocate_node(detail::get_pointer(ptr));
pool->deallocate_node(detail::get_pointer(ptr));
else
this->derived()->get_node_pool()->get_segment_manager()->deallocate(detail::get_pointer(ptr));
pool->get_segment_manager()->deallocate((void*)detail::get_pointer(ptr));
}
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate_one()
{ return pointer(static_cast<value_type*>(this->derived()->get_node_pool()->allocate_node())); }
{
typedef typename node_pool<0>::type node_pool_t;
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
return pointer(static_cast<value_type*>(pool->allocate_node()));
}
//!Allocates many elements of size == 1 in a contiguous chunk
//!of memory. The minimum number to be allocated is min_elements,
@@ -424,13 +446,21 @@ class node_pool_allocation_impl
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
multiallocation_iterator allocate_individual(std::size_t num_elements)
{ return multiallocation_iterator(this->derived()->get_node_pool()->allocate_nodes(num_elements)); }
{
typedef typename node_pool<0>::type node_pool_t;
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
return multiallocation_iterator(pool->allocate_nodes(num_elements));
}
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one(). Never throws
void deallocate_one(const pointer &p)
{ this->derived()->get_node_pool()->deallocate_node(detail::get_pointer(p)); }
{
typedef typename node_pool<0>::type node_pool_t;
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
pool->deallocate_node(detail::get_pointer(p));
}
//!Allocates many elements of size == 1 in a contiguous chunk
//!of memory. The minimum number to be allocated is min_elements,
@@ -439,11 +469,11 @@ class node_pool_allocation_impl
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
void deallocate_individual(multiallocation_iterator it)
{ this->derived()->get_node_pool()->deallocate_nodes(it.base()); }
{ node_pool<0>::get(this->derived()->get_node_pool())->deallocate_nodes(it.base()); }
//!Deallocates all free chunks of the pool
void deallocate_free_chunks()
{ this->derived()->get_node_pool()->deallocate_free_chunks(); }
{ node_pool<0>::get(this->derived()->get_node_pool())->deallocate_free_chunks(); }
};
template<class T, class NodePool, unsigned int Version>
@@ -536,7 +566,7 @@ class cached_allocator_impl
m_cache.cached_deallocation(detail::get_pointer(ptr));
}
else{
this->get_segment_manager()->deallocate(detail::get_pointer(ptr));
this->get_segment_manager()->deallocate((void*)detail::get_pointer(ptr));
}
}

View File

@@ -253,7 +253,7 @@ class private_node_pool_impl
while(!m_chunklist.empty()){
void *addr = get_chunk_from_hook(&m_chunklist.front(), blocksize);
m_chunklist.pop_front();
mp_segment_mngr_base->deallocate(addr);
mp_segment_mngr_base->deallocate((void*)addr);
}
//Just clear free node list
m_freelist.clear();

View File

@@ -59,10 +59,19 @@ class node_allocator_base
typedef SegmentManager segment_manager;
typedef node_allocator_base
<Version, T, SegmentManager, NodesPerChunk> self_t;
typedef detail::shared_node_pool
< SegmentManager, sizeof(T), NodesPerChunk> node_pool_t;
typedef typename detail::
pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
/// @cond
template <int dummy>
struct node_pool
{
typedef detail::shared_node_pool
< SegmentManager, sizeof(T), NodesPerChunk> type;
static type *get(void *p)
{ return static_cast<type*>(p); }
};
/// @endcond
BOOST_STATIC_ASSERT((Version <=2));
@@ -104,7 +113,7 @@ class node_allocator_base
(const node_allocator_base<Version2, T2, SegmentManager2, N2>&);
//!Not assignable from other node_allocator_base
node_allocator_base& operator=(const node_allocator_base&);
//node_allocator_base& operator=(const node_allocator_base&);
/// @endcond
public:
@@ -112,14 +121,14 @@ class node_allocator_base
//!pool. Increments the reference count of the associated node pool.
//!Can throw boost::interprocess::bad_alloc
node_allocator_base(segment_manager *segment_mngr)
: mp_node_pool(detail::get_or_create_node_pool<node_pool_t>(segment_mngr)) { }
: mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
//!Copy constructor from other node_allocator_base. Increments the reference
//!count of the associated node pool. Never throws
node_allocator_base(const node_allocator_base &other)
: mp_node_pool(other.get_node_pool())
{
mp_node_pool->inc_ref_count();
node_pool<0>::get(detail::get_pointer(mp_node_pool))->inc_ref_count();
}
//!Copy constructor from related node_allocator_base. If not present, constructs
@@ -128,22 +137,30 @@ class node_allocator_base
template<class T2>
node_allocator_base
(const node_allocator_base<Version, T2, SegmentManager, NodesPerChunk> &other)
: mp_node_pool(detail::get_or_create_node_pool<node_pool_t>(other.get_segment_manager())) { }
: mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
//!Assignment from other node_allocator_base
node_allocator_base& operator=(const node_allocator_base &other)
{
node_allocator_base c(other);
swap(*this, c);
return *this;
}
//!Destructor, removes node_pool_t from memory
//!if its reference count reaches to zero. Never throws
~node_allocator_base()
{ detail::destroy_node_pool_if_last_link(detail::get_pointer(mp_node_pool)); }
{ detail::destroy_node_pool_if_last_link(node_pool<0>::get(detail::get_pointer(mp_node_pool))); }
//!Returns a pointer to the node pool.
//!Never throws
node_pool_t* get_node_pool() const
void* get_node_pool() const
{ return detail::get_pointer(mp_node_pool); }
//!Returns the segment manager.
//!Never throws
segment_manager* get_segment_manager()const
{ return mp_node_pool->get_segment_manager(); }
{ return node_pool<0>::get(detail::get_pointer(mp_node_pool))->get_segment_manager(); }
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different memory segment, the result is undefined.
@@ -152,22 +169,22 @@ class node_allocator_base
/// @cond
private:
node_pool_ptr mp_node_pool;
void_pointer mp_node_pool;
/// @endcond
};
//!Equality test for same type
//!of node_allocator_base
template<unsigned int V, class T, class S, std::size_t NodesPerChunk> inline
bool operator==(const node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
const node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
template<unsigned int V, class T, class S, std::size_t NPC> inline
bool operator==(const node_allocator_base<V, T, S, NPC> &alloc1,
const node_allocator_base<V, T, S, NPC> &alloc2)
{ return alloc1.get_node_pool() == alloc2.get_node_pool(); }
//!Inequality test for same type
//!of node_allocator_base
template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
bool operator!=(const node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
const node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
template<unsigned int V, class T, class S, std::size_t NPC> inline
bool operator!=(const node_allocator_base<V, T, S, NPC> &alloc1,
const node_allocator_base<V, T, S, NPC> &alloc2)
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); }
template < class T
@@ -283,7 +300,7 @@ class node_allocator
//!Not assignable from
//!other node_allocator
node_allocator& operator=(const node_allocator&);
//node_allocator& operator=(const node_allocator&);
public:
//!Constructor from a segment manager. If not present, constructs a node
@@ -308,7 +325,7 @@ class node_allocator
//!Returns a pointer to the node pool.
//!Never throws
node_pool_t* get_node_pool() const;
void* get_node_pool() const;
//!Returns the segment manager.
//!Never throws
@@ -342,9 +359,9 @@ class node_allocator
//!Never throws
const_pointer address(const_reference value) const;
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr);
//!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
//!Destroys object. Throws if object's
//!destructor throws
@@ -414,15 +431,15 @@ class node_allocator
//!Equality test for same type
//!of node_allocator
template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
bool operator==(const node_allocator<T, S, NodesPerChunk, F, OP> &alloc1,
const node_allocator<T, S, NodesPerChunk, F, OP> &alloc2);
template<class T, class S, std::size_t NPC> inline
bool operator==(const node_allocator<T, S, NPC> &alloc1,
const node_allocator<T, S, NPC> &alloc2);
//!Inequality test for same type
//!of node_allocator
template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
bool operator!=(const node_allocator<T, S, NodesPerChunk, F, OP> &alloc1,
const node_allocator<T, S, NodesPerChunk, F, OP> &alloc2);
template<class T, class S, std::size_t NPC> inline
bool operator!=(const node_allocator<T, S, NPC> &alloc1,
const node_allocator<T, S, NPC> &alloc2);
#endif

View File

@@ -104,6 +104,22 @@ class private_adaptive_pool_base
};
/// @cond
template <int dummy>
struct node_pool
{
typedef detail::private_adaptive_node_pool
<SegmentManager
, sizeof(T)
, NodesPerChunk
, MaxFreeChunks
, OverheadPercent
> type;
static type *get(void *p)
{ return static_cast<type*>(p); }
};
private:
//!Not assignable from related private_adaptive_pool_base
template<unsigned int Version2, class T2, class MemoryAlgorithm2, std::size_t N2, std::size_t F2, unsigned char OP2>
@@ -355,9 +371,9 @@ class private_adaptive_pool
//!Never throws
const_pointer address(const_reference value) const;
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr);
//!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
//!Destroys object. Throws if object's
//!destructor throws

View File

@@ -7,201 +7,6 @@
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
/*
#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
#define BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/interprocess/allocators/detail/node_pool.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
//!\file
//!Describes private_node_allocator pooled shared memory STL compatible allocator
namespace boost {
namespace interprocess {
//!An STL node allocator that uses a segment manager as memory
//!source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the allocator in shared memory, memory mapped-files, etc...
//!This allocator has its own node pool. NodesPerChunk is the number of nodes allocated
//!at once when the allocator needs runs out of nodes
template<class T, class SegmentManager, std::size_t NodesPerChunk>
class private_node_allocator
{
/// @cond
private:
typedef typename SegmentManager::void_pointer void_pointer;
typedef typename detail::
pointer_to_other<void_pointer, const void>::type cvoid_pointer;
typedef SegmentManager segment_manager;
typedef typename detail::pointer_to_other
<void_pointer, segment_manager>::type segment_mngr_ptr_t;
typedef private_node_allocator
<T, SegmentManager, NodesPerChunk> self_t;
typedef detail::private_node_pool
<SegmentManager, sizeof(T), NodesPerChunk> priv_node_pool_t;
/// @endcond
public:
//-------
typedef typename detail::
pointer_to_other<void_pointer, T>::type pointer;
typedef typename detail::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
typedef typename detail::add_reference
<value_type>::type reference;
typedef typename detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
//!Obtains node_allocator from other node_allocator
template<class T2>
struct rebind
{
typedef private_node_allocator<T2, SegmentManager, NodesPerChunk> other;
};
/// @cond
private:
//!Not assignable from related private_node_allocator
template<class T2, class MemoryAlgorithm2, std::size_t N2>
private_node_allocator& operator=
(const private_node_allocator<T2, MemoryAlgorithm2, N2>&);
//!Not assignable from other private_node_allocator
private_node_allocator& operator=(const private_node_allocator&);
/// @endcond
public:
//!Constructor from a segment manager
private_node_allocator(segment_manager *segment_mngr)
: m_node_pool(segment_mngr){}
//!Copy constructor from other private_node_allocator. Never throws
private_node_allocator(const private_node_allocator &other)
: m_node_pool(other.get_segment_manager()){}
//!Copy constructor from related private_node_allocator. Never throws.
template<class T2>
private_node_allocator
(const private_node_allocator<T2, SegmentManager, NodesPerChunk> &other)
: m_node_pool(other.get_segment_manager())
{}
//!Destructor, frees all used memory. Never throws
~private_node_allocator()
{}
//!Returns the segment manager. Never throws
segment_manager* get_segment_manager()const
{ return m_node_pool.get_segment_manager(); }
//!Returns the number of elements that could be allocated. Never throws
size_type max_size() const
{ return this->get_segment_manager()->get_size()/sizeof(value_type); }
//!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0)
{
(void)hint;
if(count > this->max_size())
throw bad_alloc();
else if(count == 1)
return pointer(static_cast<value_type*>(m_node_pool.allocate_node()));
else
return pointer(static_cast<value_type*>
(m_node_pool.get_segment_manager()->allocate(sizeof(T)*count)));
}
//!Deallocate allocated memory. Never throws
void deallocate(const pointer &ptr, size_type count)
{
if(count == 1)
m_node_pool.deallocate_node(detail::get_pointer(ptr));
else
m_node_pool.get_segment_manager()->deallocate(detail::get_pointer(ptr));
}
//!Deallocates all free chunks of the pool
void deallocate_free_chunks()
{ m_node_pool.deallocate_free_chunks(); }
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different shared memory segments, the result is undefined.
friend void swap(self_t &alloc1,self_t &alloc2)
{ alloc1.m_node_pool.swap(alloc2.m_node_pool); }
//These functions are obsolete. These are here to conserve
//backwards compatibility with containers using them...
//!Returns address of mutable object.
//!Never throws
pointer address(reference value) const
{ return pointer(boost::addressof(value)); }
//!Returns address of non mutable object.
//!Never throws
const_pointer address(const_reference value) const
{ return const_pointer(boost::addressof(value)); }
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr)
{ new(detail::get_pointer(ptr)) value_type; }
//!Destroys object. Throws if object's
//!destructor throws
void destroy(const pointer &ptr)
{ BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
/// @cond
private:
priv_node_pool_t m_node_pool;
/// @endcond
};
//!Equality test for same type of private_node_allocator
template<class T, class S, std::size_t NodesPerChunk> inline
bool operator==(const private_node_allocator<T, S, NodesPerChunk> &alloc1,
const private_node_allocator<T, S, NodesPerChunk> &alloc2)
{ return &alloc1 == &alloc2; }
//!Inequality test for same type of private_node_allocator
template<class T, class S, std::size_t NodesPerChunk> inline
bool operator!=(const private_node_allocator<T, S, NodesPerChunk> &alloc1,
const private_node_allocator<T, S, NodesPerChunk> &alloc2)
{
return &alloc1 != &alloc2;
}
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
*/
//////////////////////////////////////////////////////////////////////////////
//
@@ -303,6 +108,19 @@ class private_node_allocator_base
};
/// @cond
template <int dummy>
struct node_pool
{
typedef detail::private_node_pool
<SegmentManager
, sizeof(T)
, NodesPerChunk
> type;
static type *get(void *p)
{ return static_cast<type*>(p); }
};
private:
//!Not assignable from related private_node_allocator_base
template<unsigned int Version2, class T2, class MemoryAlgorithm2, std::size_t N2>
@@ -356,15 +174,15 @@ class private_node_allocator_base
};
//!Equality test for same type of private_node_allocator_base
template<unsigned int V, class T, class S, std::size_t NodesPerChunk> inline
bool operator==(const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
template<unsigned int V, class T, class S, std::size_t NPC> inline
bool operator==(const private_node_allocator_base<V, T, S, NPC> &alloc1,
const private_node_allocator_base<V, T, S, NPC> &alloc2)
{ return &alloc1 == &alloc2; }
//!Inequality test for same type of private_node_allocator_base
template<unsigned int V, class T, class S, std::size_t NodesPerChunk> inline
bool operator!=(const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
template<unsigned int V, class T, class S, std::size_t NPC> inline
bool operator!=(const private_node_allocator_base<V, T, S, NPC> &alloc1,
const private_node_allocator_base<V, T, S, NPC> &alloc2)
{ return &alloc1 != &alloc2; }
template < class T
@@ -539,9 +357,9 @@ class private_node_allocator
//!Never throws
const_pointer address(const_reference value) const;
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr);
//!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
//!Destroys object. Throws if object's
//!destructor throws

View File

@@ -658,7 +658,7 @@ class deque : protected deque_base<T, Alloc>
void push_back(const value_type& t)
{
if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
++this->members_.m_finish.m_cur;
}
else
@@ -669,7 +669,7 @@ class deque : protected deque_base<T, Alloc>
void push_back(const detail::moved_object<value_type> &mt)
{
if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
++this->members_.m_finish.m_cur;
}
else
@@ -679,7 +679,7 @@ class deque : protected deque_base<T, Alloc>
void push_back(value_type &&mt)
{
if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
++this->members_.m_finish.m_cur;
}
else
@@ -690,7 +690,7 @@ class deque : protected deque_base<T, Alloc>
void push_front(const value_type& t)
{
if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(t);
new((void*)(detail::get_pointer(this->members_.m_start.m_cur)- 1))value_type(t);
--this->members_.m_start.m_cur;
}
else
@@ -701,7 +701,7 @@ class deque : protected deque_base<T, Alloc>
void push_front(const detail::moved_object<value_type> &mt)
{
if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(mt);
new((void*)(detail::get_pointer(this->members_.m_start.m_cur)- 1))value_type(mt);
--this->members_.m_start.m_cur;
}
else
@@ -711,7 +711,7 @@ class deque : protected deque_base<T, Alloc>
void push_front(value_type &&mt)
{
if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(move(mt));
new((void*)(detail::get_pointer(this->members_.m_start.m_cur)- 1))value_type(move(mt));
--this->members_.m_start.m_cur;
}
else
@@ -1217,7 +1217,7 @@ class deque : protected deque_base<T, Alloc>
this->priv_reserve_map_at_back();
*(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
BOOST_TRY {
new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
}
@@ -1235,7 +1235,7 @@ class deque : protected deque_base<T, Alloc>
this->priv_reserve_map_at_back();
*(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
BOOST_TRY {
new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
}
@@ -1251,7 +1251,7 @@ class deque : protected deque_base<T, Alloc>
this->priv_reserve_map_at_back();
*(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
BOOST_TRY {
new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
}
@@ -1271,7 +1271,7 @@ class deque : protected deque_base<T, Alloc>
BOOST_TRY {
this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
new(detail::get_pointer(this->members_.m_start.m_cur))value_type(t);
new((void*)detail::get_pointer(this->members_.m_start.m_cur))value_type(t);
}
BOOST_CATCH(...){
++this->members_.m_start;
@@ -1289,7 +1289,7 @@ class deque : protected deque_base<T, Alloc>
BOOST_TRY {
this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
new(detail::get_pointer(this->members_.m_start.m_cur))value_type(mt);
new((void*)detail::get_pointer(this->members_.m_start.m_cur))value_type(mt);
}
BOOST_CATCH(...){
++this->members_.m_start;
@@ -1306,7 +1306,7 @@ class deque : protected deque_base<T, Alloc>
BOOST_TRY {
this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
new(detail::get_pointer(this->members_.m_start.m_cur))value_type(move(mt));
new((void*)detail::get_pointer(this->members_.m_start.m_cur))value_type(move(mt));
}
BOOST_CATCH(...){
++this->members_.m_start;

View File

@@ -145,15 +145,15 @@ struct node_alloc_holder
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
template<class Convertible>
static void construct(const NodePtr &ptr, const Convertible &value)
{ new(detail::get_pointer(ptr)) Node(value); }
{ new((void*)detail::get_pointer(ptr)) Node(value); }
#else
template<class Convertible>
static void construct(const NodePtr &ptr, Convertible &&value)
{ new(detail::get_pointer(ptr)) Node(forward<Convertible>(value)); }
{ new((void*)detail::get_pointer(ptr)) Node(forward<Convertible>(value)); }
#endif
static void construct(const NodePtr &ptr)
{ new(detail::get_pointer(ptr)) Node(); }
{ new((void*)detail::get_pointer(ptr)) Node(); }
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
template<class Convertible1, class Convertible2>

View File

@@ -308,7 +308,7 @@ class basic_string_base
}
void construct(pointer p, const value_type &value = value_type())
{ new(detail::get_pointer(p)) value_type(value); }
{ new((void*)detail::get_pointer(p)) value_type(value); }
void destroy(pointer p, size_type n)
{

View File

@@ -301,8 +301,8 @@ struct vector_alloc_holder
const pointer &reuse,
allocator_v2)
{
return this->alloc().allocation_command(command, limit_size, preferred_size,
received_size, reuse);
return this->alloc().allocation_command
(command, limit_size, preferred_size, received_size, reuse);
}
size_type next_capacity(size_type additional_objects) const
@@ -434,7 +434,7 @@ class vector : private detail::vector_alloc_holder<A>
//This is the optimized move iterator for copy constructors
//so that std::copy and similar can use memcpy
typedef typename detail::if_c
<base_t::trivial_copy
<base_t::trivial_copy || !is_movable<value_type>::value
,T*
,detail::move_iterator<T*>
>::type copy_move_it;
@@ -442,7 +442,7 @@ class vector : private detail::vector_alloc_holder<A>
//This is the optimized move iterator for assignments
//so that std::uninitialized_copy and similar can use memcpy
typedef typename detail::if_c
<base_t::trivial_assign
<base_t::trivial_assign || !is_movable<value_type>::value
,T*
,detail::move_iterator<T*>
>::type assign_move_it;
@@ -859,7 +859,7 @@ class vector : private detail::vector_alloc_holder<A>
{
if (this->members_.m_size < this->members_.m_capacity){
//There is more memory, just construct a new object at the end
new(detail::get_pointer(this->members_.m_start) + this->members_.m_size)value_type(x);
new((void*)(detail::get_pointer(this->members_.m_start) + this->members_.m_size))value_type(x);
++this->members_.m_size;
}
else{
@@ -878,7 +878,7 @@ class vector : private detail::vector_alloc_holder<A>
{
if (this->members_.m_size < this->members_.m_capacity){
//There is more memory, just construct a new object at the end
new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(mx);
new((void*)detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(mx);
++this->members_.m_size;
}
else{
@@ -890,7 +890,7 @@ class vector : private detail::vector_alloc_holder<A>
{
if (this->members_.m_size < this->members_.m_capacity){
//There is more memory, just construct a new object at the end
new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(move(mx));
new((void*)detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(move(mx));
++this->members_.m_size;
}
else{
@@ -1101,7 +1101,7 @@ class vector : private detail::vector_alloc_holder<A>
T *ptr = detail::get_pointer(this->members_.m_start + this->members_.m_size);
while(n--){
//Default construct
new(ptr++)T();
new((void*)ptr++)T();
++this->members_.m_size;
}
}
@@ -1241,9 +1241,9 @@ class vector : private detail::vector_alloc_holder<A>
std::uninitialized_copy(copy_move_it(old_finish - n), copy_move_it(old_finish), old_finish);
this->members_.m_size += n;
//Copy previous to last objects to the initialized end
std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish - n), old_finish);
std::copy_backward(assign_move_it(pos), assign_move_it(old_finish - n), old_finish);
//Insert new objects in the pos
std::copy(first, last, detail::get_pointer(pos));
std::copy(first, last, pos);
}
else {
//The new elements don't fit in the [pos, end()) range. Copy
@@ -1254,12 +1254,12 @@ class vector : private detail::vector_alloc_holder<A>
this->members_.m_size += n - elems_after;
//Copy old [pos, end()) elements to the uninitialized memory
std::uninitialized_copy
( copy_move_it(detail::get_pointer(pos))
( copy_move_it(pos)
, copy_move_it(old_finish)
, detail::get_pointer(this->members_.m_start) + this->members_.m_size);
this->members_.m_size += elems_after;
//Copy first new elements in pos
std::copy(first, mid, detail::get_pointer(pos));
std::copy(first, mid, pos);
}
}
@@ -1277,7 +1277,7 @@ class vector : private detail::vector_alloc_holder<A>
//the start of the new buffer
new_finish = std::uninitialized_copy
( copy_move_it(detail::get_pointer(this->members_.m_start))
, copy_move_it(detail::get_pointer(pos))
, copy_move_it(pos)
, old_finish = new_finish);
construted_values_destroyer.increment_size(new_finish - old_finish);
//Initialize new objects, starting from previous point
@@ -1287,9 +1287,9 @@ class vector : private detail::vector_alloc_holder<A>
//Initialize from the rest of the old buffer,
//starting from previous point
new_finish = std::uninitialized_copy
( copy_move_it(detail::get_pointer(pos))
( copy_move_it(pos)
, copy_move_it(detail::get_pointer(this->members_.m_start) + this->members_.m_size)
, detail::get_pointer(new_finish));
, new_finish);
//All construction successful, disable rollbacks
construted_values_destroyer.release();
@@ -1345,13 +1345,11 @@ class vector : private detail::vector_alloc_holder<A>
//Copy first old values before pos, after that the
//new objects
boost::interprocess::uninitialized_copy_copy
(copy_move_it(old_start), copy_move_it(detail::get_pointer(pos)), first, last, detail::get_pointer(new_start));
(copy_move_it(old_start), copy_move_it(pos), first, last, new_start);
UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore);
//Now initialize the rest of memory with the last old values
std::uninitialized_copy
( copy_move_it(detail::get_pointer(pos))
, copy_move_it(old_finish)
, detail::get_pointer(new_start) + elemsbefore + n);
(copy_move_it(pos), copy_move_it(old_finish), new_start + elemsbefore + n);
//All new elements correctly constructed, avoid new element destruction
new_values_destroyer.release();
this->members_.m_size = old_size + n;
@@ -1376,17 +1374,13 @@ class vector : private detail::vector_alloc_holder<A>
//Copy first old values before pos, after that the
//new objects
boost::interprocess::uninitialized_copy_copy
( copy_move_it(old_start)
, copy_move_it(detail::get_pointer(pos))
, first, last, detail::get_pointer(new_start));
(copy_move_it(old_start), copy_move_it(pos), first, last, new_start);
UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore);
size_type raw_gap = s_before - (elemsbefore + n);
//Now initialize the rest of s_before memory with the
//first of elements after new values
std::uninitialized_copy
( copy_move_it(detail::get_pointer(pos))
, copy_move_it(detail::get_pointer(pos) + raw_gap)
, detail::get_pointer(new_start) + elemsbefore + n);
(copy_move_it(pos), copy_move_it(pos + raw_gap), new_start + elemsbefore + n);
//All new elements correctly constructed, avoid new element destruction
new_values_destroyer.release();
//All new elements correctly constructed, avoid old element destruction
@@ -1394,7 +1388,7 @@ class vector : private detail::vector_alloc_holder<A>
//Update size since we have a contiguous buffer
this->members_.m_size = old_size + s_before;
//Now copy remaining last objects in the old buffer begin
T *to_destroy = std::copy(assign_move_it(detail::get_pointer(pos) + raw_gap), assign_move_it(old_finish), old_start);
T *to_destroy = std::copy(assign_move_it(pos + raw_gap), assign_move_it(old_finish), old_start);
//Now destroy redundant elements except if they were moved and
//they have trivial destructor after move
size_type n_destroy = old_finish - to_destroy;
@@ -1460,24 +1454,22 @@ class vector : private detail::vector_alloc_holder<A>
//Copy the first part of old_begin to raw_mem
T *start_n = old_start + difference_type(s_before);
std::uninitialized_copy
( copy_move_it(old_start)
, copy_move_it(start_n)
, detail::get_pointer(new_start));
(copy_move_it(old_start), copy_move_it(start_n), new_start);
//The buffer is all constructed until old_end,
//release destroyer and update size
old_values_destroyer.release();
this->members_.m_size = old_size + s_before;
//Now copy the second part of old_begin overwriting himself
T* next = std::copy(assign_move_it(start_n), assign_move_it(detail::get_pointer(pos)), old_start);
T* next = std::copy(assign_move_it(start_n), assign_move_it(pos), old_start);
if(do_after){
//Now copy the new_beg elements
std::copy(first, before_end, detail::get_pointer(next));
std::copy(first, before_end, next);
}
else{
//Now copy the all the new elements
T* move_start = std::copy(first, last, detail::get_pointer(next));
T* move_start = std::copy(first, last, next);
//Now displace old_end elements
T* move_end = std::copy(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish), detail::get_pointer(move_start));
T* move_end = std::copy(assign_move_it(pos), assign_move_it(old_finish), move_start);
//Destroy remaining moved elements from old_end except if
//they have trivial destructor after being moved
difference_type n_destroy = s_before - n;
@@ -1513,9 +1505,7 @@ class vector : private detail::vector_alloc_holder<A>
size_type n_new_init = difference_type(s_before) - elemsbefore;
std::advance(mid, n_new_init);
boost::interprocess::uninitialized_copy_copy
( copy_move_it(old_start)
, copy_move_it(detail::get_pointer(pos))
, first, mid, detail::get_pointer(new_start));
(copy_move_it(old_start), copy_move_it(pos), first, mid, new_start);
//The buffer is all constructed until old_end,
//release destroyer and update size
old_values_destroyer.release();
@@ -1529,7 +1519,7 @@ class vector : private detail::vector_alloc_holder<A>
//Copy all new elements
T* move_start = std::copy(mid, last, old_start);
//Displace old_end
T* move_end = std::copy(copy_move_it(detail::get_pointer(pos)), copy_move_it(old_finish), detail::get_pointer(move_start));
T* move_end = std::copy(copy_move_it(pos), copy_move_it(old_finish), move_start);
//Destroy remaining moved elements from old_end except if they
//have trivial destructor after being moved
difference_type n_destroy = s_before - n;
@@ -1584,14 +1574,12 @@ class vector : private detail::vector_alloc_holder<A>
//First copy the part of old_end raw_mem
T* finish_n = old_finish - difference_type(n_after);
std::uninitialized_copy
( copy_move_it(detail::get_pointer(finish_n))
, copy_move_it(old_finish)
, old_finish);
(copy_move_it(finish_n), copy_move_it(old_finish), old_finish);
this->members_.m_size += n_after;
//Displace the rest of old_end to the new position
std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(detail::get_pointer(finish_n)), old_finish);
std::copy_backward(assign_move_it(pos), assign_move_it(finish_n), old_finish);
//Now overwrite with new_end
std::copy(first, last, detail::get_pointer(pos));
std::copy(first, last, pos);
}
else {
//The raw_mem from end will divide new_end part
@@ -1610,13 +1598,10 @@ class vector : private detail::vector_alloc_holder<A>
std::advance(mid, elemsafter);
//First initialize data in raw memory
boost::interprocess::uninitialized_copy_copy
( mid, last
, copy_move_it(detail::get_pointer(pos))
, copy_move_it(old_finish)
, old_finish);
( mid, last, copy_move_it(pos), copy_move_it(old_finish), old_finish);
this->members_.m_size += n_after;
//Now copy the part of new_end over constructed elements
std::copy(first, mid, detail::get_pointer(pos));
std::copy(first, mid, pos);
}
}
}

View File

@@ -43,7 +43,7 @@ inline void construct_in_place_impl(T* dest, const InpIt &source, detail::true_)
template<class T, class InpIt>
inline void construct_in_place_impl(T* dest, const InpIt &source, detail::false_)
{
new(dest)T(*source);
new((void*)dest)T(*source);
}
} //namespace detail {
@@ -58,7 +58,7 @@ inline void construct_in_place(T* dest, InpIt source)
template<class T, class U, class D>
inline void construct_in_place(T *dest, default_construct_iterator<U, D>)
{
new(dest)T();
new((void*)dest)T();
}
template<class InIt, class OutIt>

View File

@@ -30,4 +30,5 @@
#pragma warning (disable : 4711) // function selected for automatic inline expansion
#pragma warning (disable : 4786) // identifier truncated in debug info
#pragma warning (disable : 4996) // 'function': was declared deprecated
#pragma warning (disable : 4197) // top-level volatile in cast is ignored
#endif

View File

@@ -79,7 +79,7 @@ class move_return
public:
typedef T type;
move_return(T& returned)
move_return(const T& returned)
: m_moved(moved_object<T>(returned))
{}

View File

@@ -17,7 +17,7 @@
# pragma once
#endif
//#include <functional>
#include <cstddef>
namespace boost {
namespace interprocess {
@@ -121,6 +121,24 @@ struct identity
{ return x; }
};
template<std::size_t S>
struct ls_zeros
{
static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value);
};
template<>
struct ls_zeros<0>
{
static const std::size_t value = 0;
};
template<>
struct ls_zeros<1>
{
static const std::size_t value = 0;
};
} //namespace detail {
} //namespace interprocess {
} //namespace boost {

View File

@@ -48,13 +48,13 @@ struct Ctor0Arg : public placement_destroy<T>
self_t operator++(int) { return *this; }
void construct(void *mem)
{ new(mem)T; }
{ new((void*)mem)T; }
virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)
{
T* memory = static_cast<T*>(mem);
T* memory = (T*)(mem);
for(constructed = 0; constructed < num; ++constructed)
new(memory++)T;
new((void*)memory++)T;
}
};
@@ -88,13 +88,13 @@ struct Ctor0Arg : public placement_destroy<T>
// : p1((P1 &)p_1), p2((P2 &)p_2) {}
//
// void construct(void *mem)
// { new(object)T(m_p1, m_p2); }
// { new((void*)object)T(m_p1, m_p2); }
//
// virtual void construct_n(void *mem
// , std::size_t num
// , std::size_t &constructed)
// {
// T* memory = static_cast<T*>(mem);
// T* memory = (T*)(mem);
// for(constructed = 0; constructed < num; ++constructed){
// this->construct(memory++, IsIterator());
// this->do_increment(IsIterator());
@@ -103,10 +103,10 @@ struct Ctor0Arg : public placement_destroy<T>
//
// private:
// void construct(void *mem, detail::true_)
// { new(mem)T(*m_p1, *m_p2); }
// { new((void*)mem)T(*m_p1, *m_p2); }
//
// void construct(void *mem, detail::false_)
// { new(mem)T(m_p1, m_p2); }
// { new((void*)mem)T(m_p1, m_p2); }
//
// P1 &m_p1; P2 &m_p2;
// };
@@ -163,7 +163,7 @@ struct Ctor0Arg : public placement_destroy<T>
, std::size_t num \
, std::size_t &constructed) \
{ \
T* memory = static_cast<T*>(mem); \
T* memory = (T*)(mem); \
for(constructed = 0; constructed < num; ++constructed){ \
this->construct(memory++, IsIterator()); \
this->do_increment(IsIterator()); \
@@ -172,10 +172,10 @@ struct Ctor0Arg : public placement_destroy<T>
\
private: \
void construct(void *mem, detail::true_) \
{ new(mem)T(BOOST_PP_ENUM_PARAMS(n, *m_p)); } \
{ new((void*)mem)T(BOOST_PP_ENUM_PARAMS(n, *m_p)); } \
\
void construct(void *mem, detail::false_) \
{ new(mem)T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \
{ new((void*)mem)T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \
\
BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \
}; \

View File

@@ -373,11 +373,24 @@ inline std::size_t get_rounded_size(std::size_t orig_size, std::size_t round_to)
return ((orig_size-1)/round_to+1)*round_to;
}
//Truncates "orig_size" to a multiple of "multiple" bytes.
inline std::size_t get_truncated_size(std::size_t orig_size, std::size_t multiple)
{
return orig_size/multiple*multiple;
}
//Rounds "orig_size" by excess to round_to bytes. round_to must be power of two
inline std::size_t get_rounded_size_po2(std::size_t orig_size, std::size_t round_to)
{
return ((orig_size-1)&(~(round_to-1))) + round_to;
}
//Truncates "orig_size" to a multiple of "multiple" bytes. multiple must be power of two
inline std::size_t get_truncated_size_po2(std::size_t orig_size, std::size_t multiple)
{
return (orig_size & (~(multiple-1)));
}
template <std::size_t OrigSize, std::size_t RoundTo>
struct ct_rounded_size
{

View File

@@ -98,7 +98,7 @@ class message_queue
//!Sends a message stored in buffer "buffer" with size "buffer_size" in the
//!message queue with priority "priority". If the message queue is full
//!the sender is retries until time "abs_time" is reached. Returns true if
//!the sender retries until time "abs_time" is reached. Returns true if
//!the message has been successfully sent. Returns false if timeout is reached.
//!Throws interprocess_error on error.
bool timed_send (const void *buffer, std::size_t buffer_size,
@@ -106,23 +106,23 @@ class message_queue
//!Receives a message from the message queue. The message is stored in buffer
//!"buffer", which has size "buffer_size". The received message has size
//!"recvd_size" and priority "priority". If the message queue is full
//!the sender is blocked. Throws interprocess_error on error.
//!"recvd_size" and priority "priority". If the message queue is empty
//!the receiver is blocked. Throws interprocess_error on error.
void receive (void *buffer, std::size_t buffer_size,
std::size_t &recvd_size,unsigned int &priority);
//!Receives a message from the message queue. The message is stored in buffer
//!"buffer", which has size "buffer_size". The received message has size
//!"recvd_size" and priority "priority". If the message queue is full
//!the sender is not blocked and returns false, otherwise returns true.
//!"recvd_size" and priority "priority". If the message queue is empty
//!the receiver is not blocked and returns false, otherwise returns true.
//!Throws interprocess_error on error.
bool try_receive (void *buffer, std::size_t buffer_size,
std::size_t &recvd_size,unsigned int &priority);
//!Receives a message from the message queue. The message is stored in buffer
//!"buffer", which has size "buffer_size". The received message has size
//!"recvd_size" and priority "priority". If the message queue is full
//!the sender is retries until time "abs_time" is reached. Returns true if
//!"recvd_size" and priority "priority". If the message queue is empty
//!the receiver retries until time "abs_time" is reached. Returns true if
//!the message has been successfully sent. Returns false if timeout is reached.
//!Throws interprocess_error on error.
bool timed_receive (void *buffer, std::size_t buffer_size,

View File

@@ -45,6 +45,8 @@ namespace interprocess {
/// @cond
namespace detail{ class interprocess_tester; }
namespace detail{ class raw_mapped_region_creator; }
/// @endcond
//!The mapped_region class represents a portion or region created from a
@@ -140,6 +142,7 @@ class mapped_region
#endif
friend class detail::interprocess_tester;
friend class detail::raw_mapped_region_creator;
void dont_close_on_destruction();
/// @endcond
};
@@ -362,9 +365,9 @@ inline void mapped_region::priv_close()
m_base = 0;
}
#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
if(m_file_mapping_hnd){
if(m_file_mapping_hnd != detail::invalid_file()){
winapi::close_handle(m_file_mapping_hnd);
m_file_mapping_hnd = 0;
m_file_mapping_hnd = detail::invalid_file();
}
#endif
}

View File

@@ -23,6 +23,8 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/iterators.hpp>
#include <boost/interprocess/detail/math_functions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
@@ -281,6 +283,101 @@ class memory_algorithm_common
return this_type::priv_allocate_many(memory_algo, &elem_bytes, n_elements, 0);
}
static bool calculate_lcm_and_needs_backwards_lcmed
(std::size_t backwards_multiple, std::size_t received_size, std::size_t size_to_achieve,
std::size_t &lcm_out, std::size_t &needs_backwards_lcmed_out)
{
// Now calculate lcm
std::size_t max = backwards_multiple;
std::size_t min = Alignment;
std::size_t needs_backwards;
std::size_t needs_backwards_lcmed;
std::size_t lcm;
std::size_t current_forward;
//Swap if necessary
if(max < min){
std::size_t tmp = min;
min = max;
max = tmp;
}
//Check if it's power of two
if((backwards_multiple & (backwards_multiple-1)) == 0){
if(0 != (size_to_achieve & ((backwards_multiple-1)))){
return false;
}
lcm = max;
//If we want to use minbytes data to get a buffer between maxbytes
//and minbytes if maxbytes can't be achieved, calculate the
//biggest of all possibilities
current_forward = detail::get_truncated_size_po2(received_size, backwards_multiple);
needs_backwards = size_to_achieve - current_forward;
assert((needs_backwards % backwards_multiple) == 0);
needs_backwards_lcmed = detail::get_rounded_size_po2(needs_backwards, lcm);
lcm_out = lcm;
needs_backwards_lcmed_out = needs_backwards_lcmed;
return true;
}
//Check if it's multiple of alignment
else if((backwards_multiple & (Alignment - 1u)) == 0){
lcm = backwards_multiple;
current_forward = detail::get_truncated_size(received_size, backwards_multiple);
//No need to round needs_backwards because backwards_multiple == lcm
needs_backwards_lcmed = needs_backwards = size_to_achieve - current_forward;
assert((needs_backwards_lcmed & (Alignment - 1u)) == 0);
lcm_out = lcm;
needs_backwards_lcmed_out = needs_backwards_lcmed;
return true;
}
//Check if it's multiple of the half of the alignmment
else if((backwards_multiple & ((Alignment/2u) - 1u)) == 0){
lcm = backwards_multiple*2u;
current_forward = detail::get_truncated_size(received_size, backwards_multiple);
needs_backwards_lcmed = needs_backwards = size_to_achieve - current_forward;
if(0 != (needs_backwards_lcmed & (Alignment-1)))
//while(0 != (needs_backwards_lcmed & (Alignment-1)))
needs_backwards_lcmed += backwards_multiple;
assert((needs_backwards_lcmed % lcm) == 0);
lcm_out = lcm;
needs_backwards_lcmed_out = needs_backwards_lcmed;
return true;
}
//Check if it's multiple of the half of the alignmment
else if((backwards_multiple & ((Alignment/4u) - 1u)) == 0){
std::size_t remainder;
lcm = backwards_multiple*4u;
current_forward = detail::get_truncated_size(received_size, backwards_multiple);
needs_backwards_lcmed = needs_backwards = size_to_achieve - current_forward;
//while(0 != (needs_backwards_lcmed & (Alignment-1)))
//needs_backwards_lcmed += backwards_multiple;
if(0 != (remainder = ((needs_backwards_lcmed & (Alignment-1))>>(Alignment/8u)))){
if(backwards_multiple & Alignment/2u){
needs_backwards_lcmed += (remainder)*backwards_multiple;
}
else{
needs_backwards_lcmed += (4-remainder)*backwards_multiple;
}
}
assert((needs_backwards_lcmed % lcm) == 0);
lcm_out = lcm;
needs_backwards_lcmed_out = needs_backwards_lcmed;
return true;
}
else{
lcm = detail::lcm(max, min);
}
//If we want to use minbytes data to get a buffer between maxbytes
//and minbytes if maxbytes can't be achieved, calculate the
//biggest of all possibilities
current_forward = detail::get_truncated_size(received_size, backwards_multiple);
needs_backwards = size_to_achieve - current_forward;
assert((needs_backwards % backwards_multiple) == 0);
needs_backwards_lcmed = detail::get_rounded_size(needs_backwards, lcm);
lcm_out = lcm;
needs_backwards_lcmed_out = needs_backwards_lcmed;
return true;
}
static multiallocation_iterator allocate_many
( MemoryAlgorithm *memory_algo
, const std::size_t *elem_sizes

View File

@@ -564,7 +564,7 @@ inline std::pair<T*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
T *reuse_ptr)
{
std::pair<void*, bool> ret = priv_allocation_command
(command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T));
(command, limit_size, preferred_size, received_size, (void*)reuse_ptr, sizeof(T));
BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of<T>::value));
return std::pair<T *, bool>(static_cast<T*>(ret.first), ret.second);

View File

@@ -651,7 +651,7 @@ inline std::pair<T*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignmen
T *reuse_ptr)
{
std::pair<void*, bool> ret = priv_allocation_command
(command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T));
(command, limit_size, preferred_size, received_size, (void*)reuse_ptr, sizeof(T));
BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of<T>::value));
return std::pair<T *, bool>(static_cast<T*>(ret.first), ret.second);
@@ -776,26 +776,16 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
assert(prev_block->m_size == reuse->m_prev_size);
algo_impl_t::assert_alignment(prev_block);
//Let's calculate the number of extra bytes of data before the current
//block's begin. The value is a multiple of backwards_multiple
std::size_t needs_backwards = preferred_size -
detail::get_truncated_size(received_size, backwards_multiple);
const std::size_t lcm = detail::lcm(max_value(backwards_multiple, (std::size_t)Alignment)
,min_value(backwards_multiple, (std::size_t)Alignment));
//If we want to use min_size data to get a buffer between preferred_size
//and min_size if preferred_size can't be achieved, calculate the
//biggest of all possibilities
if(!only_preferred_backwards){
needs_backwards = min_size - detail::get_truncated_size(received_size, backwards_multiple);
std::size_t needs_backwards_aligned;
std::size_t lcm;
if(!algo_impl_t::calculate_lcm_and_needs_backwards_lcmed
( backwards_multiple
, received_size
, only_preferred_backwards ? preferred_size : min_size
, lcm, needs_backwards_aligned)){
return 0;
}
assert((needs_backwards % backwards_multiple) == 0);
const std::size_t needs_backwards_aligned =
detail::get_rounded_size(needs_backwards, lcm);
//Check if previous block has enough size
if(std::size_t(prev_block->m_size*Alignment) >= needs_backwards_aligned){
//Now take all next space. This will succeed
@@ -857,10 +847,8 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
m_header.m_imultiset.erase(Imultiset::s_iterator_to(*prev_block));
//Just merge the whole previous block
needs_backwards = detail::get_truncated_size
(prev_block->m_size*Alignment, backwards_multiple);
//received_size = received_size/backwards_multiple*backwards_multiple + needs_backwards;
received_size = received_size + needs_backwards;
//prev_block->m_size*Alignment is multiple of lcm (and backwards_multiple)
received_size = received_size + prev_block->m_size*Alignment;
m_header.m_allocated += prev_block->m_size*Alignment;
//Now update sizes

View File

@@ -53,9 +53,6 @@ class offset_ptr
{
/// @cond
typedef offset_ptr<PointedType> self_t;
typedef const PointedType * const_pointer_t;
typedef typename detail::add_reference
<const PointedType>::type const_reference_t;
void unspecified_bool_type_func() const {}
typedef void (self_t::*unspecified_bool_type)() const;
@@ -64,6 +61,9 @@ class offset_ptr
__declspec(noinline) //this workaround is needed for msvc-8.0 and msvc-9.0
#endif
void set_offset(const volatile void *ptr)
{ set_offset((const void*)ptr); }
void set_offset(const void *ptr)
{
const char *p = static_cast<const char*>(const_cast<const void*>(ptr));
//offset == 1 && ptr != 0 is not legal for this pointer
@@ -402,68 +402,44 @@ namespace intrusive {
//Predeclaration to avoid including header
template<class VoidPointer, std::size_t N>
struct has_pointer_plus_bit;
struct max_pointer_plus_bits;
template<std::size_t N>
struct has_pointer_plus_bit<boost::interprocess::offset_ptr<void>, N>
template<std::size_t Alignment>
struct max_pointer_plus_bits<boost::interprocess::offset_ptr<void>, Alignment>
{
static const bool value = (N % 4u == 0);
//The offset ptr can embed one bit less than the alignment since it
//uses offset == 1 to store the null pointer.
static const std::size_t value = ::boost::interprocess::detail::ls_zeros<Alignment>::value - 1;
};
//Predeclaration
template<class Pointer>
struct pointer_plus_bit;
template<class Pointer, std::size_t NumBits>
struct pointer_plus_bits;
//Specialization
template<class T>
struct pointer_plus_bit<boost::interprocess::offset_ptr<T> >
template<class T, std::size_t NumBits>
struct pointer_plus_bits<boost::interprocess::offset_ptr<T>, NumBits>
{
typedef boost::interprocess::offset_ptr<T> pointer;
//Bits are stored in the lower bits of the pointer except the LSB,
//because this bit is used to represent the null pointer.
static const std::size_t Mask = ((std::size_t(1) << NumBits)-1)<<1u;
static pointer get_pointer(const pointer &n)
{ return (T*)(std::size_t(n.get()) & ~std::size_t(2u)); }
{ return (T*)(std::size_t(n.get()) & ~std::size_t(Mask)); }
static void set_pointer(pointer &n, pointer p)
{ n = (T*)(std::size_t(p.get()) | (std::size_t(n.get()) & std::size_t(2u))); }
static bool get_bit(const pointer &n)
{ return 0 != (std::size_t(n.get()) & std::size_t(2u)); }
static void set_bit(pointer &n, bool c)
{ n = (T*)(std::size_t(get_pointer(n).get()) | (std::size_t(c) << 1u)); }
};
//Predeclaration to avoid including header
template<class VoidPointer, std::size_t N>
struct has_pointer_plus_2_bits;
template<std::size_t N>
struct has_pointer_plus_2_bits<boost::interprocess::offset_ptr<void>, N>
{
static const bool value = (N % 8u == 0);
};
//Predeclaration
template<class Pointer>
struct pointer_plus_2_bits;
template<class T>
struct pointer_plus_2_bits<boost::interprocess::offset_ptr<T> >
{
typedef boost::interprocess::offset_ptr<T> pointer;
static pointer get_pointer(const pointer &n)
{ return (T*)(std::size_t(n.get()) & ~std::size_t(6u)); }
static void set_pointer(pointer &n, pointer p)
{ n = (T*)(std::size_t(p.get()) | (std::size_t(n.get()) & std::size_t(6u))); }
{
std::size_t pint = std::size_t(p.get());
assert(0 == (std::size_t(pint) & Mask));
n = (T*)(pint | (std::size_t(n.get()) & std::size_t(Mask)));
}
static std::size_t get_bits(const pointer &n)
{ return(std::size_t(n.get()) & std::size_t(6u)) >> 1u; }
{ return(std::size_t(n.get()) & std::size_t(Mask)) >> 1u; }
static void set_bits(pointer &n, std::size_t b)
{
assert(b < 4);
assert(b < (std::size_t(1) << NumBits));
n = (T*)(std::size_t(get_pointer(n).get()) | (b << 1u));
}
};

View File

@@ -86,11 +86,23 @@ inline bool interprocess_condition::do_timed_wait(bool tout_enabled,
if(now >= abs_time) return false;
}
typedef boost::interprocess::scoped_lock<interprocess_mutex> InternalLock;
//The enter interprocess_mutex guarantees that while executing a notification,
//no other thread can execute the do_timed_wait method.
{
//---------------------------------------------------------------
boost::interprocess::scoped_lock<interprocess_mutex> lock(m_enter_mut);
InternalLock lock;
if(tout_enabled){
InternalLock dummy(m_enter_mut, abs_time);
lock = move(dummy);
}
else{
InternalLock dummy(m_enter_mut);
lock = move(dummy);
}
if(!lock)
return false;
//---------------------------------------------------------------
//We increment the waiting thread count protected so that it will be
//always constant when another thread enters the notification logic.
@@ -146,7 +158,18 @@ inline bool interprocess_condition::do_timed_wait(bool tout_enabled,
//Notification occurred, we will lock the checking interprocess_mutex so that
//if a notify_one notification occurs, only one thread can exit
//---------------------------------------------------------------
boost::interprocess::scoped_lock<interprocess_mutex> lock(m_check_mut);
InternalLock lock;
if(tout_enabled){
InternalLock dummy(m_check_mut, abs_time);
lock = move(dummy);
}
else{
InternalLock dummy(m_check_mut);
lock = move(dummy);
}
if(!lock)
return false;
//---------------------------------------------------------------
boost::uint32_t result = detail::atomic_cas32
((boost::uint32_t*)&m_command, SLEEP, NOTIFY_ONE);

View File

@@ -20,6 +20,7 @@
#include <boost/interprocess/exceptions.hpp>
#include <cassert>
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
//!\file
@@ -106,62 +107,6 @@ class file_lock
private:
file_handle_t m_file_hnd;
bool timed_acquire_file_lock
(file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
{
//Obtain current count and target time
boost::posix_time::ptime now = microsec_clock::universal_time();
using namespace boost::detail;
if(now >= abs_time) return false;
do{
if(!try_acquire_file_lock(hnd, acquired))
return false;
if(acquired)
return true;
else{
now = microsec_clock::universal_time();
if(now >= abs_time){
acquired = false;
return true;
}
// relinquish current time slice
winapi::sched_yield();
}
}while (true);
}
bool timed_acquire_file_lock_sharable
(file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
{
//Obtain current count and target time
boost::posix_time::ptime now = microsec_clock::universal_time();
using namespace boost::detail;
if(now >= abs_time) return false;
do{
if(!try_acquire_file_lock_sharable(hnd, acquired))
return false;
if(acquired)
return true;
else{
now = microsec_clock::universal_time();
if(now >= abs_time){
acquired = false;
return true;
}
// relinquish current time slice
winapi::sched_yield();
}
}while (true);
}
bool timed_acquire_file_lock
(file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
{
@@ -172,7 +117,7 @@ class file_lock
if(now >= abs_time) return false;
do{
if(!try_acquire_file_lock(hnd, acquired))
if(!detail::try_acquire_file_lock(hnd, acquired))
return false;
if(acquired)
@@ -185,7 +130,7 @@ class file_lock
return true;
}
// relinquish current time slice
sleep(0);
detail::thread_yield();
}
}while (true);
}
@@ -200,7 +145,7 @@ class file_lock
if(now >= abs_time) return false;
do{
if(!try_acquire_file_lock_sharable(hnd, acquired))
if(!detail::try_acquire_file_lock_sharable(hnd, acquired))
return false;
if(acquired)
@@ -213,7 +158,7 @@ class file_lock
return true;
}
// relinquish current time slice
::sleep(0);
detail::thread_yield();
}
}while (true);
}
@@ -259,7 +204,7 @@ inline bool file_lock::try_lock()
inline bool file_lock::timed_lock(const boost::posix_time::ptime &abs_time)
{
bool result;
if(!detail::timed_acquire_file_lock(m_file_hnd, result, abs_time)){
if(!this->timed_acquire_file_lock(m_file_hnd, result, abs_time)){
error_info err(system_error_code());
throw interprocess_exception(err);
}
@@ -295,7 +240,7 @@ inline bool file_lock::try_lock_sharable()
inline bool file_lock::timed_lock_sharable(const boost::posix_time::ptime &abs_time)
{
bool result;
if(!detail::timed_acquire_file_lock_sharable(m_file_hnd, result, abs_time)){
if(!this->timed_acquire_file_lock_sharable(m_file_hnd, result, abs_time)){
error_info err(system_error_code());
throw interprocess_exception(err);
}

View File

@@ -159,7 +159,9 @@ class named_condition
//unlock internal first to avoid deadlock with near simultaneous waits
lock_inverter<Lock> inverted_lock(lock);
scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock);
scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
if(!external_unlock) return false;
scoped_lock<interprocess_mutex> internal_lock(*this->mutex(), abs_time);
if(!internal_lock) return false;
return this->condition()->timed_wait(internal_lock, abs_time);
}
#endif

View File

@@ -169,7 +169,7 @@ inline mode_t windows_shared_memory::get_mode() const
inline bool windows_shared_memory::priv_open_or_create
(detail::create_enum_t type, const char *filename, mode_t mode, std::size_t size)
{
m_name = filename;
m_name = filename ? filename : "";
unsigned long file_map_access = 0;
unsigned long map_access = 0;

54
proj/to-do.txt Normal file
View File

@@ -0,0 +1,54 @@
-> Implement zero_memory flag for allocation_command
-> The general allocation funtion can be improved with some fixed size allocation bins.
-> Adapt error reporting to TR1 system exceptions
-> Improve exception messages
-> Movability of containers should depend on the no-throw guarantee of allocators copy constructor
-> Check self-assignment for vectors
-> Update writing a new memory allocator explaining new functions (like alignment)
-> private node allocators could take the number of nodes as a runtime parameter.
-> Explain how to build intrusive indexes.
-> Add intrusive index types as available indexes.
-> Add maximum alignment allocation limit in PageSize bytes. Otherwise, we can't
guarantee alignment for process-shared allocations.
-> Add default algorithm and index types. The user does not need to know how are
they implemented.
-> Add private mapping to managed classes.
-> Add unique_ptr documentation.
-> Pass max size check in allocation to node pools
-> Add atomic_func explanation in docs
-> Once shrink to fit indexes is implemented test all memory has been deallocated
in tests to detect leaks/implementation failures.
-> Improve allocate_many functions to allocate all the nodes forming a singly
linked list of nodes.
-> Use in-place expansion capabilities to shrink_to_fit and reserve functions
from iunordered_index.
-> Optimize copy_n with std::copy in vector. Revise other functions to improve optimizations
-> Keep an eye on container iterator constness issue to bring Interprocess containers up-to-date.
-> change unique_ptr to avoid using compressed_pair
-> Improve unique_ptr test to test move assignment and other goodies like assigment from null
-> barrier_test fails on MacOS X on PowerPC.
-> void allocator instantiations fail.

View File

@@ -415,6 +415,34 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "offset_ptr_test", "offset_p
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_shared_memory", "doc_anonymous_shared_memory.vcproj", "{6DE178C3-12FE-6032-4FC7-879B63B9F651}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "anonymous_shared_memory_test", "anonymous_shared_memory_test.vcproj", "{58DE8A13-4FA7-6252-36FE-B3A0A6D92812}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_unordered_map", "doc_unordered_map.vcproj", "{9C185DF3-B75F-1928-8F6D-735108AABE62}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_multi_index", "doc_multi_index.vcproj", "{918C5DF3-1928-B73F-F626-7358518CBE62}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_test", "unordered_test.vcproj", "{C3CE1183-09F2-A46A-4FE6-D06BA7923A02}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_index_test", "multi_index_test.vcproj", "{9285DFD3-1928-F662-CB73-73518CB53A62}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "file_lock_test", "file_lock_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792639}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -839,6 +867,34 @@ Global
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
{6DE178C3-12FE-6032-4FC7-879B63B9F651}.Debug.ActiveCfg = Debug|Win32
{6DE178C3-12FE-6032-4FC7-879B63B9F651}.Debug.Build.0 = Debug|Win32
{6DE178C3-12FE-6032-4FC7-879B63B9F651}.Release.ActiveCfg = Release|Win32
{6DE178C3-12FE-6032-4FC7-879B63B9F651}.Release.Build.0 = Release|Win32
{58DE8A13-4FA7-6252-36FE-B3A0A6D92812}.Debug.ActiveCfg = Debug|Win32
{58DE8A13-4FA7-6252-36FE-B3A0A6D92812}.Debug.Build.0 = Debug|Win32
{58DE8A13-4FA7-6252-36FE-B3A0A6D92812}.Release.ActiveCfg = Release|Win32
{58DE8A13-4FA7-6252-36FE-B3A0A6D92812}.Release.Build.0 = Release|Win32
{9C185DF3-B75F-1928-8F6D-735108AABE62}.Debug.ActiveCfg = Debug|Win32
{9C185DF3-B75F-1928-8F6D-735108AABE62}.Debug.Build.0 = Debug|Win32
{9C185DF3-B75F-1928-8F6D-735108AABE62}.Release.ActiveCfg = Release|Win32
{9C185DF3-B75F-1928-8F6D-735108AABE62}.Release.Build.0 = Release|Win32
{918C5DF3-1928-B73F-F626-7358518CBE62}.Debug.ActiveCfg = Debug|Win32
{918C5DF3-1928-B73F-F626-7358518CBE62}.Debug.Build.0 = Debug|Win32
{918C5DF3-1928-B73F-F626-7358518CBE62}.Release.ActiveCfg = Release|Win32
{918C5DF3-1928-B73F-F626-7358518CBE62}.Release.Build.0 = Release|Win32
{C3CE1183-09F2-A46A-4FE6-D06BA7923A02}.Debug.ActiveCfg = Debug|Win32
{C3CE1183-09F2-A46A-4FE6-D06BA7923A02}.Debug.Build.0 = Debug|Win32
{C3CE1183-09F2-A46A-4FE6-D06BA7923A02}.Release.ActiveCfg = Release|Win32
{C3CE1183-09F2-A46A-4FE6-D06BA7923A02}.Release.Build.0 = Release|Win32
{9285DFD3-1928-F662-CB73-73518CB53A62}.Debug.ActiveCfg = Debug|Win32
{9285DFD3-1928-F662-CB73-73518CB53A62}.Debug.Build.0 = Debug|Win32
{9285DFD3-1928-F662-CB73-73518CB53A62}.Release.ActiveCfg = Release|Win32
{9285DFD3-1928-F662-CB73-73518CB53A62}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792639}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792639}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792639}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792639}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="anonymous_shared_memory_test"
ProjectGUID="{58DE8A13-4FA7-6252-36FE-B3A0A6D92812}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/anonymous_shared_memory_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
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)/mapped_file_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/anonymous_shared_memory_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/anonymous_shared_memory_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
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)/anonymous_shared_memory_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="{37F46E1-7A60-7AB5-3256-2B3A235E7E2F}">
<File
RelativePath="..\..\test\anonymous_shared_memory_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="doc_anonymous_shared_memory"
ProjectGUID="{6DE178C3-12FE-6032-4FC7-879B63B9F651}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/doc_anonymous_shared_memory"
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)/doc_anonymous_shared_memory_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/doc_anonymous_shared_memory.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/doc_anonymous_shared_memory"
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)/doc_anonymous_shared_memory.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="{4F7371DF-A5DA-6437-60A6-22A352A2D7FF}">
<File
RelativePath="..\..\example\doc_anonymous_shared_memory.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{95431998-8EB8-9BCA-44D0-ECD5A7BE2B52}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="doc_multi_index"
ProjectGUID="{918C5DF3-1928-B73F-F626-7358518CBE62}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/doc_multi_index"
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)/doc_multi_index_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/doc_multi_index.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/doc_multi_index"
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)/doc_multi_index.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="{F37CE270-AB55-7439-5C26-1C5A5E3A21EA}">
<File
RelativePath="..\..\example\doc_multi_index.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="doc_unordered_map"
ProjectGUID="{9C185DF3-B75F-1928-8F6D-735108AABE62}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/doc_unordered_map"
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)/doc_unordered_map_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/doc_unordered_map.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/doc_unordered_map"
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)/doc_unordered_map.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="{4737FCC1-7AB5-7A06-4376-1C5A5E3A21EA}">
<File
RelativePath="..\..\example\doc_unordered_map.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="file_lock_test"
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792639}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/file_lock_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"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/file_lock_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/file_lock_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/file_lock_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/file_lock_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="{7FCFEF41-3746-C7A5-8B8E-A352A2F22D7F}">
<File
RelativePath="..\..\test\file_lock_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{95393980-8912-4b74-66A0-607BE52EB5FB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -315,6 +315,9 @@
Name="Managed Memory Classes"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\..\..\boost\interprocess\anonymous_shared_memory.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\creation_tags.hpp">
</File>

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="multi_index_test"
ProjectGUID="{9285DFD3-1928-F662-CB73-73518CB53A62}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/multi_index_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)/multi_index_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/multi_index_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/multi_index_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)/multi_index_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="{FE2726C0-356C-55BB-7439-12C5EB3E06AA}">
<File
RelativePath="..\..\test\multi_index_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="unordered_test"
ProjectGUID="{C3CE1183-09F2-A46A-4FE6-D06BA7923A02}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/unordered_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)/unordered_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/unordered_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/unordered_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)/unordered_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="{437BC07F-3132-A066-7AC5-32A2B22D75AF}">
<File
RelativePath="..\..\test\unordered_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -11,6 +11,8 @@
#include "node_pool_test.hpp"
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
#include <vector>
int main ()
{
using namespace boost::interprocess;

View File

@@ -41,7 +41,6 @@ typedef list<int, shmem_node_allocator_v1_t> MyShmListV1;
typedef vector<int, shmem_node_allocator_t> MyShmVector;
typedef vector<int, shmem_node_allocator_v1_t> MyShmVectorV1;
int main ()
{
if(test::list_test<managed_shared_memory, MyShmList, true>())

View File

@@ -114,17 +114,17 @@ class allocator_v1
//!Deallocates memory previously allocated. Never throws
void deallocate(const pointer &ptr, size_type)
{ mp_mngr->deallocate(detail::get_pointer(ptr)); }
/*
{ mp_mngr->deallocate((void*)detail::get_pointer(ptr)); }
//!Construct object, calling constructor.
//!Throws if T(const T&) throws
void construct(const pointer &ptr, const_reference value)
{ new(detail::get_pointer(ptr)) value_type(value); }
{ new((void*)detail::get_pointer(ptr)) value_type(value); }
//!Destroys object. Throws if object's destructor throws
void destroy(const pointer &ptr)
{ BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
*/
//!Returns the number of elements that could be allocated. Never throws
size_type max_size() const
{ return mp_mngr->get_size(); }

View File

@@ -0,0 +1,54 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2007. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <iostream>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/anonymous_shared_memory.hpp>
#include <cstddef>
#include <exception>
using namespace boost::interprocess;
int main ()
{
try{
const std::size_t MemSize = 99999*2;
{
//Now check anonymous mapping
mapped_region region(anonymous_shared_memory(MemSize));
//Write pattern
unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
for(std::size_t i = 0
;i < MemSize
;++i, ++pattern){
*pattern = static_cast<unsigned char>(i);
}
//Check pattern
pattern = static_cast<unsigned char*>(region.get_address());
for(std::size_t i = 0
;i < MemSize
;++i, ++pattern){
if(*pattern != static_cast<unsigned char>(i)){
return 1;
}
}
}
}
catch(std::exception &exc){
std::cout << "Unhandled exception: " << exc.what() << std::endl;
return 1;
}
return 0;
}
#include <boost/interprocess/detail/config_end.hpp>

View File

@@ -82,26 +82,26 @@ class dummy_test_allocator
template<class T2>
dummy_test_allocator(const dummy_test_allocator<T2> &)
{}
/*
pointer address(reference value)
{ return pointer(addressof(value)); }
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
*/
pointer allocate(size_type, cvoid_ptr = 0)
{ return 0; }
void deallocate(const pointer &, size_type)
{ }
/*
template<class Convertible>
void construct(pointer, const Convertible &)
{}
void destroy(pointer)
{}
*/
size_type max_size() const
{ return 0; }

View File

@@ -85,26 +85,26 @@ class expand_bwd_test_allocator
expand_bwd_test_allocator(const expand_bwd_test_allocator<T2> &other)
: mp_buffer(other.mp_buffer), m_size(other.m_size)
, m_offset(other.m_offset), m_allocations(0){ }
/*
pointer address(reference value)
{ return pointer(addressof(value)); }
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
*/
pointer allocate(size_type , cvoid_ptr hint = 0)
{ (void)hint; return 0; }
void deallocate(const pointer &, size_type)
{}
/*
template<class Convertible>
void construct(pointer ptr, const Convertible &value)
{ new((void*)ptr) value_type(value); }
void destroy(pointer ptr)
{ (*ptr).~value_type(); }
*/
size_type max_size() const
{ return m_size; }

View File

@@ -15,6 +15,7 @@
#include <vector>
#include "expand_bwd_test_allocator.hpp"
#include <algorithm>
#include <boost/type_traits/remove_volatile.hpp>
namespace boost { namespace interprocess { namespace test {
@@ -107,7 +108,8 @@ template<class VectorWithExpandBwdAllocator>
bool test_insert_with_expand_bwd()
{
typedef typename VectorWithExpandBwdAllocator::value_type value_type;
typedef std::vector<value_type> Vect;
typedef typename boost::remove_volatile<value_type>::type non_volatile_value_type;
typedef std::vector<non_volatile_value_type> Vect;
const int MemorySize = 1000;
//Distance old and new buffer
@@ -131,37 +133,42 @@ bool test_insert_with_expand_bwd()
for(int iteration = 0; iteration < Iterations; ++iteration)
{
Vect memory;
memory.resize(MemorySize);
value_type *memory = new value_type[MemorySize];
try {
std::vector<non_volatile_value_type> initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
initial_data[i] = i;
}
Vect initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
initial_data[i] = value_type(i);
}
Vect data_to_insert;
data_to_insert.resize(InsertSize[iteration]);
for(int i = 0; i < InsertSize[iteration]; ++i){
data_to_insert[i] = -i;
}
Vect data_to_insert;
data_to_insert.resize(InsertSize[iteration]);
for(int i = 0; i < InsertSize[iteration]; ++i){
data_to_insert[i] = value_type(-i);
expand_bwd_test_allocator<value_type> alloc
((value_type*)&memory[0], MemorySize, Offset[iteration]);
VectorWithExpandBwdAllocator vector(alloc);
vector.insert( vector.begin()
, initial_data.begin(), initial_data.end());
vector.insert( vector.begin() + Position[iteration]
, data_to_insert.begin(), data_to_insert.end());
initial_data.insert(initial_data.begin() + Position[iteration]
, data_to_insert.begin(), data_to_insert.end());
//Now check that values are equal
if(!CheckEqualVector(vector, initial_data)){
std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
<< " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
<< " Iteration: " << iteration << std::endl;
return false;
}
}
expand_bwd_test_allocator<value_type> alloc
(&memory[0], memory.size(), Offset[iteration]);
VectorWithExpandBwdAllocator vector(alloc);
vector.insert( vector.begin()
, initial_data.begin(), initial_data.end());
vector.insert( vector.begin() + Position[iteration]
, data_to_insert.begin(), data_to_insert.end());
initial_data.insert(initial_data.begin() + Position[iteration]
, data_to_insert.begin(), data_to_insert.end());
//Now check that values are equal
if(!CheckEqualVector(vector, initial_data)){
std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
<< " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
<< " Iteration: " << iteration << std::endl;
return false;
catch(...){
delete []((non_volatile_value_type*)memory);
throw;
}
delete []((non_volatile_value_type*)memory);
}
return true;
@@ -173,7 +180,8 @@ template<class VectorWithExpandBwdAllocator>
bool test_assign_with_expand_bwd()
{
typedef typename VectorWithExpandBwdAllocator::value_type value_type;
typedef std::vector<value_type> Vect;
typedef typename boost::remove_volatile<value_type>::type non_volatile_value_type;
typedef std::vector<non_volatile_value_type> Vect;
const int MemorySize = 200;
const int Offset[] = { 50, 50, 50};
@@ -183,41 +191,46 @@ bool test_assign_with_expand_bwd()
for(int iteration = 0; iteration <Iterations; ++iteration)
{
Vect memory;
memory.resize(MemorySize);
value_type *memory = new value_type[MemorySize];
try {
//Create initial data
std::vector<non_volatile_value_type> initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
initial_data[i] = i;
}
//Create initial data
Vect initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
initial_data[i] = i;
//Create data to assign
std::vector<non_volatile_value_type> data_to_assign;
data_to_assign.resize(AssignSize[iteration]);
for(int i = 0; i < AssignSize[iteration]; ++i){
data_to_assign[i] = -i;
}
//Insert initial data to the vector to test
expand_bwd_test_allocator<value_type> alloc
(&memory[0], MemorySize, Offset[iteration]);
VectorWithExpandBwdAllocator vector(alloc);
vector.insert( vector.begin()
, initial_data.begin(), initial_data.end());
//Assign data
vector.assign(data_to_assign.begin(), data_to_assign.end());
initial_data.assign(data_to_assign.begin(), data_to_assign.end());
//Now check that values are equal
if(!CheckEqualVector(vector, initial_data)){
std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
<< " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
<< " Iteration: " << iteration << std::endl;
return false;
}
}
//Create data to assign
Vect data_to_assign;
data_to_assign.resize(AssignSize[iteration]);
for(int i = 0; i < AssignSize[iteration]; ++i){
data_to_assign[i] = -i;
}
//Insert initial data to the vector to test
expand_bwd_test_allocator<value_type> alloc
(&memory[0], memory.size(), Offset[iteration]);
VectorWithExpandBwdAllocator vector(alloc);
vector.insert( vector.begin()
, initial_data.begin(), initial_data.end());
//Assign data
vector.assign(data_to_assign.begin(), data_to_assign.end());
initial_data.assign(data_to_assign.begin(), data_to_assign.end());
//Now check that values are equal
if(!CheckEqualVector(vector, initial_data)){
std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
<< " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
<< " Iteration: " << iteration << std::endl;
return false;
catch(...){
delete []((typename boost::remove_volatile<value_type>::type*)memory);
throw;
}
delete []((typename boost::remove_volatile<value_type>::type*)memory);
}
return true;

62
test/file_lock_test.cpp Normal file
View File

@@ -0,0 +1,62 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2008. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include "mutex_test_template.hpp"
#include "sharable_mutex_test_template.hpp"
#include "get_process_id_name.hpp"
#include <fstream>
#include <cstdio>
using namespace boost::interprocess;
//This wrapper is necessary to have a default constructor
//in generic mutex_test_template functions
class file_lock_lock_test_wrapper
: public boost::interprocess::file_lock
{
public:
file_lock_lock_test_wrapper()
: boost::interprocess::file_lock(test::get_process_id_name())
{}
};
int main ()
{
//Destroy and create file
{
std::remove(test::get_process_id_name());
std::ofstream file(test::get_process_id_name());
if(!file){
return 1;
}
file_lock flock(test::get_process_id_name());
{
scoped_lock<file_lock> sl(flock);
}
{
scoped_lock<file_lock> sl(flock, try_to_lock);
}
{
scoped_lock<file_lock> sl(flock, test::delay(1));
}
}
//test::test_all_lock<file_lock_lock_test_wrapper>();
//test::test_all_mutex<false, file_lock_lock_test_wrapper>();
//test::test_all_sharable_mutex<false, file_lock_lock_test_wrapper>();
std::remove(test::get_process_id_name());
return 0;
}
#include <boost/interprocess/detail/config_end.hpp>

View File

@@ -26,6 +26,9 @@ template class boost::interprocess::list<test::movable_and_copyable_int,
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
typedef list<int, ShmemAllocator> MyList;
typedef allocator<volatile int, managed_shared_memory::segment_manager> ShmemVolatileAllocator;
typedef list<volatile int, ShmemVolatileAllocator> MyVolatileList;
typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
typedef list<test::movable_int, ShmemMoveAllocator> MyMoveList;
@@ -37,6 +40,9 @@ int main ()
if(test::list_test<managed_shared_memory, MyList, true>())
return 1;
if(test::list_test<managed_shared_memory, MyVolatileList, true>())
return 1;
if(test::list_test<managed_shared_memory, MyMoveList, true>())
return 1;

149
test/multi_index_test.cpp Normal file
View File

@@ -0,0 +1,149 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/allocators/adaptive_pool.hpp>
#include <boost/interprocess/allocators/cached_adaptive_pool.hpp>
#include <boost/interprocess/allocators/private_adaptive_pool.hpp>
#include <boost/interprocess/allocators/node_allocator.hpp>
#include <boost/interprocess/allocators/cached_node_allocator.hpp>
#include <boost/interprocess/allocators/private_node_allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
using namespace boost::interprocess;
namespace bmi = boost::multi_index;
typedef managed_shared_memory::allocator<char>::type char_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator>shm_string;
//Data to insert in shared memory
struct employee
{
int id;
int age;
shm_string name;
employee( int id_
, int age_
, const char *name_
, const char_allocator &a)
: id(id_), age(age_), name(name_, a)
{}
};
//Tags
struct id{};
struct age{};
struct name{};
// Explicit instantiations to catch compile-time errors
template class bmi::multi_index_container<
employee,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
bmi::ordered_non_unique<
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
allocator<employee,managed_shared_memory::segment_manager>
>;
// Explicit instantiations to catch compile-time errors
template class bmi::multi_index_container<
employee,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
bmi::ordered_non_unique<
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
adaptive_pool<employee,managed_shared_memory::segment_manager>
>;
/*
// Explicit instantiations to catch compile-time errors
template class bmi::multi_index_container<
employee,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
bmi::ordered_non_unique<
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
cached_adaptive_pool<employee,managed_shared_memory::segment_manager>
>;
// Explicit instantiations to catch compile-time errors
template class bmi::multi_index_container<
employee,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
bmi::ordered_non_unique<
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
private_adaptive_pool<employee,managed_shared_memory::segment_manager>
>;
*/
// Explicit instantiations to catch compile-time errors
template class bmi::multi_index_container<
employee,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
bmi::ordered_non_unique<
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
node_allocator<employee,managed_shared_memory::segment_manager>
>;
/*
// Explicit instantiations to catch compile-time errors
template class bmi::multi_index_container<
employee,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
bmi::ordered_non_unique<
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
cached_node_allocator<employee,managed_shared_memory::segment_manager>
>;
// Explicit instantiations to catch compile-time errors
template class bmi::multi_index_container<
employee,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
bmi::ordered_non_unique<
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
private_node_allocator<employee,managed_shared_memory::segment_manager>
>;
*/
int main ()
{
return 0;
}
#include <boost/interprocess/detail/config_end.hpp>

View File

@@ -13,6 +13,7 @@
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/anonymous_shared_memory.hpp>
#include <string>
#include "get_process_id_name.hpp"
@@ -113,6 +114,28 @@ int main ()
}
}
}
{
//Now check anonymous mapping
mapped_region region(anonymous_shared_memory(FileSize));
//Write pattern
unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
for(std::size_t i = 0
;i < FileSize
;++i, ++pattern){
*pattern = static_cast<unsigned char>(i);
}
//Check pattern
pattern = static_cast<unsigned char*>(region.get_address());
for(std::size_t i = 0
;i < FileSize
;++i, ++pattern){
if(*pattern != static_cast<unsigned char>(i)){
return 1;
}
}
}
}
catch(std::exception &exc){
shared_memory_object::remove(test::get_process_id_name());

View File

@@ -61,7 +61,7 @@ template class boost::interprocess::multimap
//Customize managed_shared_memory class
typedef basic_managed_shared_memory
<char,
simple_seq_fit<mutex_family, void*>,
simple_seq_fit<mutex_family, offset_ptr<void> >,
map_index
> my_managed_shared_memory;

94
test/unordered_test.cpp Normal file
View File

@@ -0,0 +1,94 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2008. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include "get_process_id_name.hpp"
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <functional> //std::equal_to
#include <boost/functional/hash.hpp> //boost::hash
namespace bip = boost::interprocess;
typedef bip::allocator<int, bip::managed_shared_memory::segment_manager> ShmemAllocator;
typedef boost::unordered_set<int, boost::hash<int>, std::equal_to<int>, ShmemAllocator> MyUnorderedSet;
typedef boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>, ShmemAllocator> MyUnorderedMultiSet;
//Explicit instantiation to catch compile-time errors
template class boost::unordered_set<int, boost::hash<int>, std::equal_to<int>, ShmemAllocator>;
template class boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>, ShmemAllocator>;
int main()
{
//Remove any other old shared memory from the system
bip::shared_memory_object::remove(bip::test::get_process_id_name());
try {
bip::managed_shared_memory shm(bip::create_only, bip::test::get_process_id_name(), 65536);
//Elements to be inserted in unordered containers
const int elements[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const int elements_size = sizeof(elements)/sizeof(elements[0]);
MyUnorderedSet *myset =
shm.construct<MyUnorderedSet>(bip::anonymous_instance)
( elements_size
, MyUnorderedSet::hasher()
, MyUnorderedSet::key_equal()
, shm.get_allocator<int>());
MyUnorderedMultiSet *mymset =
shm.construct<MyUnorderedMultiSet>(bip::anonymous_instance)
( elements_size
, MyUnorderedSet::hasher()
, MyUnorderedSet::key_equal()
, shm.get_allocator<int>());
//Insert elements and check sizes
myset->insert((&elements[0]), (&elements[elements_size]));
myset->insert((&elements[0]), (&elements[elements_size]));
mymset->insert((&elements[0]), (&elements[elements_size]));
mymset->insert((&elements[0]), (&elements[elements_size]));
if(myset->size() != (unsigned int)elements_size)
return 1;
if(mymset->size() != (unsigned int)elements_size*2)
return 1;
//Destroy elements and check sizes
myset->clear();
mymset->clear();
if(!myset->empty())
return 1;
if(!mymset->empty())
return 1;
//Destroy elements and check if memory has been deallocated
shm.destroy_ptr(myset);
shm.destroy_ptr(mymset);
shm.shrink_to_fit_indexes();
if(!shm.all_memory_deallocated())
return 1;
}
catch(...){
//Remove shared memory from the system
bip::shared_memory_object::remove(bip::test::get_process_id_name());
throw;
}
//Remove shared memory from the system
bip::shared_memory_object::remove(bip::test::get_process_id_name());
return 0;
}
#include <boost/interprocess/detail/config_end.hpp>

View File

@@ -44,7 +44,16 @@ int test_expand_bwd()
if(!test::test_all_expand_bwd<int_vector>())
return 1;
/*
//First raw volatile ints
typedef test::expand_bwd_test_allocator<volatile int>
volatile_int_allocator_type;
typedef vector<volatile int, volatile_int_allocator_type>
volatile_int_vector;
if(!test::test_all_expand_bwd<volatile_int_vector>())
return 1;
*/
//Now user defined wrapped int
typedef test::expand_bwd_test_allocator<test::int_holder>
int_holder_allocator_type;
@@ -72,6 +81,9 @@ int main()
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
typedef vector<int, ShmemAllocator> MyVector;
//typedef allocator<volatile int, managed_shared_memory::segment_manager> ShmemVolatileAllocator;
//typedef vector<volatile int, ShmemVolatileAllocator> MyVolatileVector;
typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
typedef vector<test::movable_int, ShmemMoveAllocator> MyMoveVector;
@@ -81,6 +93,9 @@ int main()
if(test::vector_test<managed_shared_memory, MyVector>())
return 1;
//if(test::vector_test<managed_shared_memory, MyVolatileVector>())
//return 1;
if(test::vector_test<managed_shared_memory, MyMoveVector>())
return 1;

View File

@@ -23,98 +23,93 @@ using namespace boost::interprocess;
int main ()
{
std::string process_name;
test::get_process_id_name(process_name);
try{
const std::size_t FileSize = 99999*2;
//Create shared memory and file mapping
windows_shared_memory mapping(create_only, process_name.c_str(), read_write, FileSize);
const char *names[2] = { test::get_process_id_name(), 0 };
for(unsigned int i = 0; i < sizeof(names)/sizeof(names[0]); ++i)
{
const std::size_t FileSize = 99999*2;
//Create a file mapping
windows_shared_memory mapping(open_only, process_name.c_str(), read_write);
windows_shared_memory mapping
(create_only, names[i], read_write, FileSize);
//Create two mapped regions, one half of the file each
mapped_region region (mapping
,read_write
,0
,FileSize/2
,0);
{
mapped_region region2(mapping
,read_write
,FileSize/2
,FileSize - FileSize/2
,0);
//Create two mapped regions, one half of the file each
mapped_region region (mapping
,read_write
,0
,FileSize/2
,0);
//Fill two regions with a pattern
unsigned char *filler = static_cast<unsigned char*>(region.get_address());
for(std::size_t i = 0
;i < FileSize/2
;++i){
*filler++ = static_cast<unsigned char>(i);
}
mapped_region region2(mapping
,read_write
,FileSize/2
,FileSize - FileSize/2
,0);
filler = static_cast<unsigned char*>(region2.get_address());
for(std::size_t i = FileSize/2
;i < FileSize
;++i){
*filler++ = static_cast<unsigned char>(i);
}
}
//Fill two regions with a pattern
unsigned char *filler = static_cast<unsigned char*>(region.get_address());
for(std::size_t i = 0
;i < FileSize/2
;++i){
*filler++ = static_cast<unsigned char>(i);
}
//See if the pattern is correct in the file using two mapped regions
{
//Create a file mapping
windows_shared_memory mapping(open_only, process_name.c_str(), read_write);
mapped_region region(mapping, read_write, 0, FileSize/2, 0);
mapped_region region2(mapping, read_write, FileSize/2, 0/*FileSize - FileSize/2*/, 0);
unsigned char *checker = (unsigned char*)region.get_address();
//Check pattern
for(std::size_t i = 0
;i < FileSize/2
;++i){
if(*checker++ != static_cast<unsigned char>(i)){
return 1;
filler = static_cast<unsigned char*>(region2.get_address());
for(std::size_t i = FileSize/2
;i < FileSize
;++i){
*filler++ = static_cast<unsigned char>(i);
}
}
//Check second half
checker = (unsigned char *)region2.get_address();
//See if the pattern is correct in the file using two mapped regions
{
mapped_region region (mapping, read_only, 0, FileSize/2, 0);
mapped_region region2(mapping, read_only, FileSize/2, FileSize - FileSize/2, 0);
//Check pattern
for(std::size_t i = FileSize/2
;i < FileSize
;++i){
if(*checker++ != static_cast<unsigned char>(i)){
return 1;
unsigned char *checker = (unsigned char*)region.get_address();
//Check pattern
for(std::size_t i = 0
;i < FileSize/2
;++i){
if(*checker++ != static_cast<unsigned char>(i)){
return 1;
}
}
//Check second half
checker = (unsigned char *)region2.get_address();
//Check pattern
for(std::size_t i = FileSize/2
;i < FileSize
;++i){
if(*checker++ != static_cast<unsigned char>(i)){
return 1;
}
}
}
}
//Now check the pattern mapping a single read only mapped_region
{
//Create a file mapping
windows_shared_memory mapping(open_only, process_name.c_str(), read_only);
//Now check the pattern mapping a single read only mapped_region
{
//Create a single regions, mapping all the file
mapped_region region (mapping, read_only);
//Create a single regions, mapping all the file
mapped_region region (mapping
,read_only);
//Check pattern
unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
for(std::size_t i = 0
;i < FileSize
;++i, ++pattern){
if(*pattern != static_cast<unsigned char>(i)){
return 1;
//Check pattern
unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
for(std::size_t i = 0
;i < FileSize
;++i, ++pattern){
if(*pattern != static_cast<unsigned char>(i)){
return 1;
}
}
}
}
}
catch(std::exception &exc){
//shared_memory_object::remove(test::get_process_id_name());
std::cout << "Unhandled exception: " << exc.what() << std::endl;
return 1;
}

View File

@@ -68,6 +68,7 @@ int main ()
std::cout << ex.what() << std::endl;
return 1;
}
return 0;
}