File: doc_intrusive.cpp

package info (click to toggle)
boost1.35 1.35.0-5
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 203,856 kB
  • ctags: 337,867
  • sloc: cpp: 938,683; xml: 56,847; ansic: 41,589; python: 18,999; sh: 11,566; makefile: 664; perl: 494; yacc: 456; asm: 353; csh: 6
file content (111 lines) | stat: -rw-r--r-- 3,586 bytes parent folder | download
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
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007. 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/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
//[doc_intrusive
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/smart_ptr/intrusive_ptr.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 ()
{
   shared_memory_object::remove("my_shmem");

   try{
      //Create shared memory
      managed_shared_memory shmem(create_only, "my_shmem", 10000);

      //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;
   }
   catch(...){
      shared_memory_object::remove("my_shmem");
      throw;
   }
   shared_memory_object::remove("my_shmem");
   //Success!
   return 0;
}
//]
#include <boost/interprocess/detail/config_end.hpp>