]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/interprocess/example/doc_intrusive.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / interprocess / example / doc_intrusive.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
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)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10
11
12 #include <boost/interprocess/detail/workaround.hpp>
13 //[doc_intrusive
14 #include <boost/interprocess/managed_shared_memory.hpp>
15 #include <boost/interprocess/smart_ptr/intrusive_ptr.hpp>
16 //<-
17 #include "../test/get_process_id_name.hpp"
18 //->
19
20 using namespace boost::interprocess;
21
22 namespace N {
23
24 //A class that has an internal reference count
25 class reference_counted_class
26 {
27 private:
28 //Non-copyable
29 reference_counted_class(const reference_counted_class &);
30 //Non-assignable
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;
38
39 public:
40 //Constructor
41 reference_counted_class(segment_manager *s_mngr)
42 : m_use_count(0), mp_segment_manager(s_mngr){}
43 //Destructor
44 ~reference_counted_class(){}
45
46 public:
47 //Returns the reference count
48 unsigned int use_count() const
49 { return m_use_count; }
50
51 //Adds a reference
52 inline friend void intrusive_ptr_add_ref(reference_counted_class * p)
53 { ++p->m_use_count; }
54
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); }
58 };
59
60 } //namespace N {
61
62 //A class that has an intrusive pointer to reference_counted_class
63 class intrusive_ptr_owner
64 {
65 typedef intrusive_ptr<N::reference_counted_class,
66 offset_ptr<void> > intrusive_ptr_t;
67 intrusive_ptr_t m_intrusive_ptr;
68
69 public:
70 //Takes a pointer to the reference counted class
71 intrusive_ptr_owner(N::reference_counted_class *ptr)
72 : m_intrusive_ptr(ptr){}
73 };
74
75 int main()
76 {
77 //Remove shared memory on construction and destruction
78 struct shm_remove
79 {
80 //<-
81 #if 1
82 shm_remove() { shared_memory_object::remove(test::get_process_id_name()); }
83 ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); }
84 #else
85 //->
86 shm_remove() { shared_memory_object::remove("MySharedMemory"); }
87 ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
88 //<-
89 #endif
90 //->
91 } remover;
92 //<-
93 (void)remover;
94 //->
95
96 //Create shared memory
97 //<-
98 #if 1
99 managed_shared_memory shmem(create_only, test::get_process_id_name(), 10000);
100 #else
101 //->
102 managed_shared_memory shmem(create_only, "MySharedMemory", 10000);
103 //<-
104 #endif
105 //->
106
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());
111
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);
116
117 //Now test that reference count is ten
118 if(ref_counted->use_count() != 10)
119 return 1;
120
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);
125
126 //Now the reference counted object should have been destroyed
127 if(shmem.find<intrusive_ptr_owner>("ref_counted").first)
128 return 1;
129 //Success!
130 return 0;
131 }
132 //]
133