forked from boostorg/interprocess
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdoc_intrusive.cpp
More file actions
133 lines (113 loc) · 3.84 KB
/
doc_intrusive.cpp
File metadata and controls
133 lines (113 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/workaround.hpp>
//[doc_intrusive
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/smart_ptr/intrusive_ptr.hpp>
//<-
#include "../test/get_process_id_name.hpp"
//->
using namespace boost::interprocess;
namespace N {
//A class that has an internal reference count
class reference_counted_class
{
private:
//Non-copyable
reference_counted_class(const reference_counted_class &);
//Non-assignable
reference_counted_class & operator=(const reference_counted_class &);
//A typedef to save typing
typedef managed_shared_memory::segment_manager segment_manager;
//This is the reference count
unsigned int m_use_count;
//The segment manager allows deletion from shared memory segment
offset_ptr<segment_manager> mp_segment_manager;
public:
//Constructor
reference_counted_class(segment_manager *s_mngr)
: m_use_count(0), mp_segment_manager(s_mngr){}
//Destructor
~reference_counted_class(){}
public:
//Returns the reference count
unsigned int use_count() const
{ return m_use_count; }
//Adds a reference
inline friend void intrusive_ptr_add_ref(reference_counted_class * p)
{ ++p->m_use_count; }
//Releases a reference
inline friend void intrusive_ptr_release(reference_counted_class * p)
{ if(--p->m_use_count == 0) p->mp_segment_manager->destroy_ptr(p); }
};
} //namespace N {
//A class that has an intrusive pointer to reference_counted_class
class intrusive_ptr_owner
{
typedef intrusive_ptr<N::reference_counted_class,
offset_ptr<void> > intrusive_ptr_t;
intrusive_ptr_t m_intrusive_ptr;
public:
//Takes a pointer to the reference counted class
intrusive_ptr_owner(N::reference_counted_class *ptr)
: m_intrusive_ptr(ptr){}
};
int main()
{
//Remove shared memory on construction and destruction
struct shm_remove
{
//<-
#if 1
shm_remove() { shared_memory_object::remove(test::get_process_id_name()); }
~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); }
#else
//->
shm_remove() { shared_memory_object::remove("MySharedMemory"); }
~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
//<-
#endif
//->
} remover;
//<-
(void)remover;
//->
//Create shared memory
//<-
#if 1
managed_shared_memory shmem(create_only, test::get_process_id_name(), 10000);
#else
//->
managed_shared_memory shmem(create_only, "MySharedMemory", 10000);
//<-
#endif
//->
//Create the unique reference counted object in shared memory
N::reference_counted_class *ref_counted =
shmem.construct<N::reference_counted_class>
("ref_counted")(shmem.get_segment_manager());
//Create an array of ten intrusive pointer owners in shared memory
intrusive_ptr_owner *intrusive_owner_array =
shmem.construct<intrusive_ptr_owner>
(anonymous_instance)[10](ref_counted);
//Now test that reference count is ten
if(ref_counted->use_count() != 10)
return 1;
//Now destroy the array of intrusive pointer owners
//This should destroy every intrusive_ptr and because of
//that reference_counted_class will be destroyed
shmem.destroy_ptr(intrusive_owner_array);
//Now the reference counted object should have been destroyed
if(shmem.find<intrusive_ptr_owner>("ref_counted").first)
return 1;
//Success!
return 0;
}
//]