File: doc_intrusive.cpp

package info (click to toggle)
boost1.83 1.83.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 545,632 kB
  • sloc: cpp: 3,857,086; xml: 125,552; ansic: 34,414; python: 25,887; asm: 5,276; sh: 4,799; ada: 1,681; makefile: 1,629; perl: 1,212; pascal: 1,139; sql: 810; yacc: 478; ruby: 102; lisp: 24; csh: 6
file content (133 lines) | stat: -rw-r--r-- 3,932 bytes parent folder | download | duplicates (6)
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
133
//////////////////////////////////////////////////////////////////////////////
//
// (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;
}
//]