• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <boost/interprocess/detail/config_begin.hpp>
11 #include <boost/interprocess/detail/workaround.hpp>
12 //[doc_scoped_ptr
13 #include <boost/interprocess/managed_shared_memory.hpp>
14 #include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
15 //<-
16 #include "../test/get_process_id_name.hpp"
17 //->
18 
19 using namespace boost::interprocess;
20 
21 class my_class
22 {};
23 
24 class my_exception
25 {};
26 
27 //A functor that destroys the shared memory object
28 template<class T>
29 class my_deleter
30 {
31    private:
32    //A typedef to save typing
33    typedef managed_shared_memory::segment_manager segment_manager;
34    //This my_deleter is created in the stack, not in shared memory,
35    //so we can use raw pointers
36    segment_manager *mp_segment_manager;
37 
38    public:
39    //This typedef will specify the pointer type that
40    //scoped_ptr will store
41    typedef T *pointer;
42    //Constructor
my_deleter(segment_manager * s_mngr)43    my_deleter(segment_manager *s_mngr)
44    : mp_segment_manager(s_mngr){}
45 
operator ()(pointer object_to_delete)46    void operator()(pointer object_to_delete)
47    {  mp_segment_manager->destroy_ptr(object_to_delete);  }
48 };
49 
main()50 int main ()
51 {
52    //Create shared memory
53    //Remove shared memory on construction and destruction
54    struct shm_remove
55    {
56    //<-
57    #if 1
58       shm_remove() { shared_memory_object::remove(test::get_process_id_name()); }
59       ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); }
60    #else
61    //->
62       shm_remove() { shared_memory_object::remove("MySharedMemory"); }
63       ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
64    //<-
65    #endif
66    //->
67    } remover;
68    //<-
69    (void)remover;
70    //->
71 
72    //<-
73    #if 1
74    managed_shared_memory shmem(create_only, test::get_process_id_name(), 10000);
75    #else
76    //->
77    managed_shared_memory shmem(create_only, "MySharedMemory", 10000);
78    //<-
79    #endif
80    //->
81 
82    //In the first try, there will be no exceptions
83    //in the second try we will throw an exception
84    for(int i = 0; i < 2; ++i){
85       //Create an object in shared memory
86       my_class * my_object = shmem.construct<my_class>("my_object")();
87       my_class * my_object2 = shmem.construct<my_class>(anonymous_instance)();
88       shmem.destroy_ptr(my_object2);
89 
90       //Since the next shared memory allocation can throw
91       //assign it to a scoped_ptr so that if an exception occurs
92       //we destroy the object automatically
93       my_deleter<my_class> d(shmem.get_segment_manager());
94 
95       try{
96          scoped_ptr<my_class, my_deleter<my_class> > s_ptr(my_object, d);
97          //Let's emulate a exception capable operation
98          //In the second try, throw an exception
99          if(i == 1){
100             throw(my_exception());
101          }
102          //If we have passed the dangerous zone
103          //we can release the scoped pointer
104          //to avoid destruction
105          s_ptr.release();
106       }
107       catch(const my_exception &){}
108       //Here, scoped_ptr is destroyed
109       //so it we haven't thrown an exception
110       //the object should be there, otherwise, destroyed
111       if(i == 0){
112          //Make sure the object is alive
113          if(!shmem.find<my_class>("my_object").first){
114             return 1;
115          }
116          //Now we can use it and delete it manually
117          shmem.destroy<my_class>("my_object");
118       }
119       else{
120          //Make sure the object has been deleted
121          if(shmem.find<my_class>("my_object").first){
122             return 1;
123          }
124       }
125    }
126    return 0;
127 }
128 //]
129 #include <boost/interprocess/detail/config_end.hpp>
130