Boost logo

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