mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
Source breaking: A shared memory object is now used including shared_memory_object.hpp header instead of shared memory.hpp. ABI breaking: Changed global mutex when initializing managed shared memory and memory mapped files. This change tries to minimize deadlocks. Source breaking: Changed shared memory, memory mapped files and mapped region's open mode to a single boost::interprocess::mode_t type. Added extra WIN32_LEAN_AND_MEAN before including DateTime headers to avoid socket redefinition errors when using Interprocess and Asio in windows. ABI breaking: mapped_region constructor no longer requires classes derived from memory_mappable, but classes the fulfill the MemoryMappable concept. Added in-place reallocation capabilities to basic_string. ABI breaking: Reimplemented and optimized small string optimization. The narrow string class has zero byte overhead with an internal 11 byte buffer in 32 systems! Added move semantics to containers. Experimental and not documented yet. Improves performance when using containers of containers. ABI breaking: End nodes of node containers (list, slist, map/set) are now embedded in the containers instead of allocated using the allocator. This allows no-throw move-constructors and improves performance. ABI breaking: slist and list containers now have constant-time size() function. The size of the container is added as a member. [SVN r35618]
222 lines
7.2 KiB
C++
222 lines
7.2 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// (C) Copyright Ion Gaztañaga 2004-2006. 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 <algorithm>
|
|
#include <memory>
|
|
#include <deque>
|
|
#include <iostream>
|
|
#include <functional>
|
|
|
|
#include <boost/interprocess/managed_shared_memory.hpp>
|
|
#include <boost/interprocess/containers/deque.hpp>
|
|
#include <boost/interprocess/indexes/flat_map_index.hpp>
|
|
#include "print_container.hpp"
|
|
#include "check_equal_containers.hpp"
|
|
#include "dummy_test_allocator.hpp"
|
|
#include "movable_int.hpp"
|
|
#include <boost/interprocess/allocators/allocator.hpp>
|
|
#include "allocator_v1.hpp"
|
|
#include <boost/interprocess/exceptions.hpp>
|
|
#include <boost/interprocess/detail/move_iterator.hpp>
|
|
#include <boost/interprocess/detail/move.hpp>
|
|
|
|
//***************************************************************//
|
|
// //
|
|
// This example repeats the same operations with std::deque and //
|
|
// shmem_deque using the node allocator //
|
|
// and compares the values of both containers //
|
|
// //
|
|
//***************************************************************//
|
|
|
|
using namespace boost::interprocess;
|
|
|
|
//Explicit instantiation to detect compilation errors
|
|
template class boost::interprocess::deque<test::movable_and_copyable_int,
|
|
test::dummy_test_allocator<test::movable_and_copyable_int> >;
|
|
|
|
//Function to check if both sets are equal
|
|
template<class V1, class V2>
|
|
bool copyable_only(V1 *shmdeque, V2 *stddeque, boost::false_type)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//Function to check if both sets are equal
|
|
template<class V1, class V2>
|
|
bool copyable_only(V1 *shmdeque, V2 *stddeque, boost::true_type)
|
|
{
|
|
typedef typename V1::value_type IntType;
|
|
std::size_t size = shmdeque->size();
|
|
stddeque->insert(stddeque->end(), 50, 1);
|
|
shmdeque->insert(shmdeque->end(), 50, 1);
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
|
|
{
|
|
IntType move_me(1);
|
|
stddeque->insert(stddeque->begin()+size/2, 50, 1);
|
|
shmdeque->insert(shmdeque->begin()+size/2, 50, move(move_me));
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
|
|
}
|
|
{
|
|
IntType move_me(2);
|
|
shmdeque->assign(shmdeque->size()/2, move(move_me));
|
|
stddeque->assign(stddeque->size()/2, 2);
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<class IntType, template<class T, class SegmentManager> class AllocatorType >
|
|
bool do_test()
|
|
{
|
|
//Customize managed_shared_memory class
|
|
typedef basic_managed_shared_memory
|
|
<char,
|
|
simple_seq_fit<mutex_family>,
|
|
flat_map_index
|
|
> my_managed_shared_memory;
|
|
|
|
//Alias AllocatorType type
|
|
typedef AllocatorType<IntType, my_managed_shared_memory::segment_manager>
|
|
shmem_allocator_t;
|
|
|
|
//Alias deque types
|
|
typedef deque<IntType, shmem_allocator_t> MyShmDeque;
|
|
typedef std::deque<int> MyStdDeque;
|
|
const int Memsize = 65536;
|
|
const char *const shMemName = "MySharedMemory";
|
|
const int max = 100;
|
|
|
|
shared_memory_object::remove(shMemName);
|
|
|
|
//Create shared memory
|
|
my_managed_shared_memory segment(create_only, shMemName, Memsize);
|
|
|
|
segment.reserve_named_objects(100);
|
|
|
|
//Shared memory allocator must be always be initialized
|
|
//since it has no default constructor
|
|
MyShmDeque *shmdeque = segment.template construct<MyShmDeque>("MyShmDeque")
|
|
(segment.get_segment_manager());
|
|
|
|
MyStdDeque *stddeque = new MyStdDeque;
|
|
|
|
try{
|
|
//Compare several shared memory deque operations with std::deque
|
|
int i;
|
|
for(i = 0; i < max; ++i){
|
|
IntType move_me(i);
|
|
shmdeque->insert(shmdeque->end(), move(move_me));
|
|
stddeque->insert(stddeque->end(), i);
|
|
}
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
|
|
|
|
typename MyShmDeque::iterator it;
|
|
typename MyShmDeque::const_iterator cit = it;
|
|
|
|
shmdeque->erase(shmdeque->begin()++);
|
|
stddeque->erase(stddeque->begin()++);
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
|
|
|
|
shmdeque->erase(shmdeque->begin());
|
|
stddeque->erase(stddeque->begin());
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
|
|
|
|
{
|
|
//Initialize values
|
|
IntType aux_vect[50];
|
|
for(int i = 0; i < 50; ++i){
|
|
IntType move_me (-1);
|
|
aux_vect[i] = move(move_me);
|
|
}
|
|
int aux_vect2[50];
|
|
for(int i = 0; i < 50; ++i){
|
|
aux_vect2[i] = -1;
|
|
}
|
|
|
|
shmdeque->insert(shmdeque->end()
|
|
,detail::make_move_iterator(&aux_vect[0])
|
|
,detail::make_move_iterator(aux_vect + 50));
|
|
stddeque->insert(stddeque->end(), aux_vect2, aux_vect2 + 50);
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
|
|
|
|
for(int i = 0, j = static_cast<int>(shmdeque->size()); i < j; ++i){
|
|
shmdeque->erase(shmdeque->begin());
|
|
stddeque->erase(stddeque->begin());
|
|
}
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
|
|
}
|
|
{
|
|
IntType aux_vect[50];
|
|
for(int i = 0; i < 50; ++i){
|
|
IntType move_me(-1);
|
|
aux_vect[i] = move(move_me);
|
|
}
|
|
int aux_vect2[50];
|
|
for(int i = 0; i < 50; ++i){
|
|
aux_vect2[i] = -1;
|
|
}
|
|
shmdeque->insert(shmdeque->begin()
|
|
,detail::make_move_iterator(&aux_vect[0])
|
|
,detail::make_move_iterator(aux_vect + 50));
|
|
stddeque->insert(stddeque->begin(), aux_vect2, aux_vect2 + 50);
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
|
|
}
|
|
|
|
if(!copyable_only(shmdeque, stddeque
|
|
,boost::integral_constant
|
|
<bool, !is_movable<IntType>::value>())){
|
|
return false;
|
|
}
|
|
|
|
shmdeque->erase(shmdeque->begin());
|
|
stddeque->erase(stddeque->begin());
|
|
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
|
|
|
|
for(i = 0; i < max; ++i){
|
|
IntType move_me(i);
|
|
shmdeque->insert(shmdeque->begin(), move(move_me));
|
|
stddeque->insert(stddeque->begin(), i);
|
|
}
|
|
if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
|
|
|
|
segment.template destroy<MyShmDeque>("MyShmDeque");
|
|
delete stddeque;
|
|
}
|
|
catch(std::exception &ex){
|
|
std::cout << ex.what() << std::endl;
|
|
return false;
|
|
}
|
|
|
|
std::cout << std::endl << "Test OK!" << std::endl;
|
|
return true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main ()
|
|
{
|
|
if(!do_test<int, allocator>())
|
|
return 1;
|
|
|
|
if(!do_test<test::movable_int, allocator>())
|
|
return 1;
|
|
|
|
if(!do_test<int, test::allocator_v1>())
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
#include <boost/interprocess/detail/config_end.hpp>
|