J
James
I am trying to develop 'generic' property map in shared memory based
on boost::any and had some problem.
Boost::interprocess and related containers in shared memory are used.
The property map will look like as below (part code):
My question is: because boost::any use "new" directly in the
constructor to construct the object
template<typename ValueType>
any(const ValueType & value)
: content(new holder<ValueType>(value))
{
}
it fails to co-work with shared memory because the object is not in
the shared memory and will not be seen by other processes.
My quick-and-dirty modification to boost::any is to replace all "new"
with "placement new" like:
template<typename ValueType>
any(const ValueType & value) /// manager is global
variable of the shared memory manager
: content(new (manager->allocate(sizeof(ValueType)))
holder<ValueType>(value))
{
}
~any()
{
if (content)
content->~placeholder();
any_allocator::shared_allocator->deallocate(content);
}
virtual placeholder * clone() const
{
return new (manager->allocate(sizeof(ValueType)))
holder(held);
}
But when trying to get the content from another process, is still
cause segfault in
any(const any & other)
: content(other.content ? other.content->clone() : 0)
{
}
any idea about that?
Thanks a lot in advance.
------------------------------------------------------------------------------------------
below my testing code where "any" is the modified version
#include "boost/interprocess/managed_shared_memory.hpp"
#include "boost/interprocess/containers/map.hpp"
#include "boost/interprocess/allocators/allocator.hpp"
#include "boost/interprocess/containers/string.hpp"
using namespace boost::interprocess;
typedef managed_shared_memory::segment_manager
segment_manager_t;
typedef allocator<char, segment_manager_t> char_allocator;
typedef allocator<void, segment_manager_t> void_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator>
char_string;
typedef char_string options_key_type;
typedef any options_mapped_type; ///<-- the
mapped value
typedef std:air<options_key_type, options_mapped_type>
options_value_type;
typedef allocator<options_value_type, segment_manager_t>
options_value_type_allocator;
typedef map<options_key_type, options_mapped_type,
std::less<options_key_type>, options_value_type_allocator>
options_type;
options_type* options;
options_value_type_allocator options_allocator_instance(segment-
(std::less<options_key_type>(), options_allocator_instance);
void_allocator string_allocator_instance(segment->get_segment_manager
());
any_allocator::shared_allocator = segment->get_segment_manager();
options->insert(options_value_type(char_string("key1",
string_allocator_instance), any(10.0)));
options->insert(options_value_type(char_string("key1",
string_allocator_instance), any(true)));
....
on boost::any and had some problem.
Boost::interprocess and related containers in shared memory are used.
The property map will look like as below (part code):
My question is: because boost::any use "new" directly in the
constructor to construct the object
template<typename ValueType>
any(const ValueType & value)
: content(new holder<ValueType>(value))
{
}
it fails to co-work with shared memory because the object is not in
the shared memory and will not be seen by other processes.
My quick-and-dirty modification to boost::any is to replace all "new"
with "placement new" like:
template<typename ValueType>
any(const ValueType & value) /// manager is global
variable of the shared memory manager
: content(new (manager->allocate(sizeof(ValueType)))
holder<ValueType>(value))
{
}
~any()
{
if (content)
content->~placeholder();
any_allocator::shared_allocator->deallocate(content);
}
virtual placeholder * clone() const
{
return new (manager->allocate(sizeof(ValueType)))
holder(held);
}
But when trying to get the content from another process, is still
cause segfault in
any(const any & other)
: content(other.content ? other.content->clone() : 0)
{
}
any idea about that?
Thanks a lot in advance.
------------------------------------------------------------------------------------------
below my testing code where "any" is the modified version
#include "boost/interprocess/managed_shared_memory.hpp"
#include "boost/interprocess/containers/map.hpp"
#include "boost/interprocess/allocators/allocator.hpp"
#include "boost/interprocess/containers/string.hpp"
using namespace boost::interprocess;
typedef managed_shared_memory::segment_manager
segment_manager_t;
typedef allocator<char, segment_manager_t> char_allocator;
typedef allocator<void, segment_manager_t> void_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator>
char_string;
typedef char_string options_key_type;
typedef any options_mapped_type; ///<-- the
mapped value
typedef std:air<options_key_type, options_mapped_type>
options_value_type;
typedef allocator<options_value_type, segment_manager_t>
options_value_type_allocator;
typedef map<options_key_type, options_mapped_type,
std::less<options_key_type>, options_value_type_allocator>
options_type;
options_type* options;
options_value_type_allocator options_allocator_instance(segment-
options = segment->construct<options_type>("options")get_segment_manager());
(std::less<options_key_type>(), options_allocator_instance);
void_allocator string_allocator_instance(segment->get_segment_manager
());
any_allocator::shared_allocator = segment->get_segment_manager();
options->insert(options_value_type(char_string("key1",
string_allocator_instance), any(10.0)));
options->insert(options_value_type(char_string("key1",
string_allocator_instance), any(true)));
....