1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2006-2012. 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 //////////////////////////////////////////////////////////////////////////////
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"); }
96 //Create shared memory
99 managed_shared_memory
shmem(create_only
, test::get_process_id_name(), 10000);
102 managed_shared_memory
shmem(create_only
, "MySharedMemory", 10000);
107 //Create the unique reference counted object in shared memory
108 N::reference_counted_class
*ref_counted
=
109 shmem
.construct
<N::reference_counted_class
>
110 ("ref_counted")(shmem
.get_segment_manager());
112 //Create an array of ten intrusive pointer owners in shared memory
113 intrusive_ptr_owner
*intrusive_owner_array
=
114 shmem
.construct
<intrusive_ptr_owner
>
115 (anonymous_instance
)[10](ref_counted
);
117 //Now test that reference count is ten
118 if(ref_counted
->use_count() != 10)
121 //Now destroy the array of intrusive pointer owners
122 //This should destroy every intrusive_ptr and because of
123 //that reference_counted_class will be destroyed
124 shmem
.destroy_ptr(intrusive_owner_array
);
126 //Now the reference counted object should have been destroyed
127 if(shmem
.find
<intrusive_ptr_owner
>("ref_counted").first
)