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 | |
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 |
43 | my_deleter(segment_manager *s_mngr) |
44 | : mp_segment_manager(s_mngr){} |
45 | |
46 | void operator()(pointer object_to_delete) |
47 | { mp_segment_manager->destroy_ptr(object_to_delete); } |
48 | }; |
49 | |
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(filename: test::get_process_id_name()); } |
59 | ~shm_remove(){ shared_memory_object::remove(filename: 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>(name: "my_object" )(); |
87 | my_class * my_object2 = shmem.construct<my_class>(name: anonymous_instance)(); |
88 | shmem.destroy_ptr(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 | BOOST_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 | BOOST_CATCH(const my_exception &){} BOOST_CATCH_END |
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>(name: "my_object" ).first){ |
114 | return 1; |
115 | } |
116 | //Now we can use it and delete it manually |
117 | shmem.destroy<my_class>(name: "my_object" ); |
118 | } |
119 | else{ |
120 | //Make sure the object has been deleted |
121 | if(shmem.find<my_class>(name: "my_object" ).first){ |
122 | return 1; |
123 | } |
124 | } |
125 | } |
126 | return 0; |
127 | } |
128 | //] |
129 | |
130 | |