Apply patch for [CVE-2012-2677][boost] ordered_malloc() overflow
[external/boost.git] / libs / interprocess / example / doc_intrusive.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2006-2009. 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 #include <boost/interprocess/detail/config_begin.hpp>
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    //Create shared memory
94    //<-
95    #if 1
96    managed_shared_memory shmem(create_only, test::get_process_id_name(), 10000);
97    #else
98    //->
99    managed_shared_memory shmem(create_only, "MySharedMemory", 10000);
100    //<-
101    #endif
102    //->
103
104    //Create the unique reference counted object in shared memory
105    N::reference_counted_class *ref_counted = 
106       shmem.construct<N::reference_counted_class>
107          ("ref_counted")(shmem.get_segment_manager());
108
109    //Create an array of ten intrusive pointer owners in shared memory
110    intrusive_ptr_owner *intrusive_owner_array = 
111       shmem.construct<intrusive_ptr_owner>
112          (anonymous_instance)[10](ref_counted);
113
114    //Now test that reference count is ten
115    if(ref_counted->use_count() != 10)
116       return 1;
117
118    //Now destroy the array of intrusive pointer owners
119    //This should destroy every intrusive_ptr and because of
120    //that reference_counted_class will be destroyed
121    shmem.destroy_ptr(intrusive_owner_array);
122
123    //Now the reference counted object should have been destroyed
124    if(shmem.find<intrusive_ptr_owner>("ref_counted").first)
125       return 1;
126    //Success!
127    return 0;
128 }
129 //]
130 #include <boost/interprocess/detail/config_end.hpp>