1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2006-2009. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #include <boost/interprocess/detail/config_begin.hpp>
12 #include <boost/interprocess/detail/workaround.hpp>
14 #include <boost/interprocess/managed_shared_memory.hpp>
15 #include <boost/interprocess/smart_ptr/intrusive_ptr.hpp>
17 #include "../test/get_process_id_name.hpp"
20 using namespace boost::interprocess;
24 //A class that has an internal reference count
25 class reference_counted_class
29 reference_counted_class(const reference_counted_class &);
31 reference_counted_class & operator=(const reference_counted_class &);
32 //A typedef to save typing
33 typedef managed_shared_memory::segment_manager segment_manager;
34 //This is the reference count
35 unsigned int m_use_count;
36 //The segment manager allows deletion from shared memory segment
37 offset_ptr<segment_manager> mp_segment_manager;
41 reference_counted_class(segment_manager *s_mngr)
42 : m_use_count(0), mp_segment_manager(s_mngr){}
44 ~reference_counted_class(){}
47 //Returns the reference count
48 unsigned int use_count() const
49 { return m_use_count; }
52 inline friend void intrusive_ptr_add_ref(reference_counted_class * p)
55 //Releases a reference
56 inline friend void intrusive_ptr_release(reference_counted_class * p)
57 { if(--p->m_use_count == 0) p->mp_segment_manager->destroy_ptr(p); }
62 //A class that has an intrusive pointer to reference_counted_class
63 class intrusive_ptr_owner
65 typedef intrusive_ptr<N::reference_counted_class,
66 offset_ptr<void> > intrusive_ptr_t;
67 intrusive_ptr_t m_intrusive_ptr;
70 //Takes a pointer to the reference counted class
71 intrusive_ptr_owner(N::reference_counted_class *ptr)
72 : m_intrusive_ptr(ptr){}
77 //Remove shared memory on construction and destruction
82 shm_remove() { shared_memory_object::remove(test::get_process_id_name()); }
83 ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); }
86 shm_remove() { shared_memory_object::remove("MySharedMemory"); }
87 ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
93 //Create shared memory
96 managed_shared_memory shmem(create_only, test::get_process_id_name(), 10000);
99 managed_shared_memory shmem(create_only, "MySharedMemory", 10000);
104 //Create the unique reference counted object in shared memory
105 N::reference_counted_class *ref_counted =
106 shmem.construct<N::reference_counted_class>
107 ("ref_counted")(shmem.get_segment_manager());
109 //Create an array of ten intrusive pointer owners in shared memory
110 intrusive_ptr_owner *intrusive_owner_array =
111 shmem.construct<intrusive_ptr_owner>
112 (anonymous_instance)[10](ref_counted);
114 //Now test that reference count is ten
115 if(ref_counted->use_count() != 10)
118 //Now destroy the array of intrusive pointer owners
119 //This should destroy every intrusive_ptr and because of
120 //that reference_counted_class will be destroyed
121 shmem.destroy_ptr(intrusive_owner_array);
123 //Now the reference counted object should have been destroyed
124 if(shmem.find<intrusive_ptr_owner>("ref_counted").first)
130 #include <boost/interprocess/detail/config_end.hpp>