2009/2/12 Ion Gaztaņaga <igaztanaga@gmail.com>
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