|
Boost Users : |
Subject: Re: [Boost-users] [Interprocess] shared_ptr in shared memory and inheritance
From: Gaetan Gaumer (gaetan.gaumer_at_[hidden])
Date: 2009-02-17 09:58:02
2009/2/12 Ion Gaztañaga <igaztanaga_at_[hidden]>
> Gaetan Gaumer wrote:
>
>>
>> First of all, if you use fixed_managed_shared_memory, you want to
>> specify the same base address in ever process, otherwise, you're
>> code won't work.
>>
>> Is it enough to create the segment with the same name in each process :
>> eg a call to the line below in each process :
>> fixed_managed_shared_memory
>> segment(open_or_create,"sharedPtrSharedMemoryTest", 2048);
>>
>
> You don't have any guarantee that the OS will map it in the same address in
> both processes.
>
Ok, I'll force the mapping to the same address for all the processes.
>
> I understand your solution but I don't know wich method I have to
>> redefine.
>> Because the problem is not really the destructor, but rather the
>> "deleter".
>> And I don't find how to redefine (and register) the base deleter to call
>> the derived one.
>> Could you help me (again...)
>>
>
> Sorry, it was just a fast idea that I haven't elaborated. But I guess this
> will be hard to implement. Inheritance and shared memory don't work very
> well
>
I tried to implement that solution by writing a customDeleter inspired
by boost::interprocess::deleter
where the only difference is the operator() :
template<class T, class SegmentManager> void customDeleter<T,
SegmentManager>::operator()(const pointer &p){
int objectId = detail::get_pointer(p)->getId();
switch (objectId){
case DERIVED_ID:
mp_mngr->destroy_ptr((derived*)(detail::get_pointer(p))); //cast to the
right type
break;
default:
mp_mngr->destroy_ptr(detail::get_pointer(p));
break;
}
}
Then I use it like this :
typedef fixed_managed_shared_memory::segment_manager
segment_manager_t;
typedef allocator<void, segment_manager_t>
void_allocator;
typedef customDeleter<base,segment_manager_t> base_Deleter;
typedef shared_ptr<base, void_allocator, base_Deleter> base_shared_ptr;
base_shared_ptr baseSP =
base_shared_ptr((dbSharableData*)segment.construct<derived>(anonymous_instance)(DERIVED_ID,3.3)
,segment.get_allocator<void>(),
base_Deleter(base_Deleter::segment_manager_pointer(segment)) );
This seems to work because the right deleter is called, and assert()
in block_header_from_value() don't fail as before.
But my program get locked in a scoped_lock at
boost/interprocess/mem_algo/rbtree_best_fit.hpp:1264 :
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
void rbtree_best_fit<MutexFamily, VoidPointer,
MemAlignment>::deallocate(void* addr)
{
if(!addr) return;
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
return this->priv_deallocate(addr);
}
I don't understand how and why there's such a lock as I work currently with
only one process.
Any hint ?
Regards,
Gaëtan
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net