1 | ////////////////////////////////////////////////////////////////////////////// |
---|---|
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2021-2021. 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/managed_shared_memory.hpp> |
12 | #include <boost/interprocess/sync/interprocess_semaphore.hpp> |
13 | #include <boost/interprocess/containers/list.hpp> |
14 | #include <cstring> |
15 | #include <cstdlib> |
16 | #include <string> |
17 | #include <iostream> |
18 | #include <cstdlib> |
19 | #include "../test/get_process_id_name.hpp" |
20 | |
21 | using namespace boost::interprocess; |
22 | |
23 | //Remove shared memory on construction and destruction |
24 | struct shm_remove |
25 | { |
26 | shm_remove() { shared_memory_object::remove(filename: test::get_process_id_name()); } |
27 | ~shm_remove(){ shared_memory_object::remove(filename: test::get_process_id_name()); } |
28 | }; |
29 | |
30 | const std::size_t MemSize = 64u*1024u; |
31 | |
32 | typedef list<int, allocator<int, managed_shared_memory::segment_manager> > |
33 | MyList; |
34 | |
35 | int main(int argc, char *argv[]) |
36 | { |
37 | std::string p_or_c = argc == 1 ? "parent": "child"; |
38 | BOOST_TRY { |
39 | if(argc == 1){ //Parent process |
40 | shm_remove remover; (void)remover; |
41 | shared_memory_object::remove(filename: test::get_process_id_name()); |
42 | shared_memory_object::remove(filename: test::get_process_id_name()); |
43 | |
44 | //Create a shared memory object. |
45 | managed_shared_memory shm (create_only, test::get_process_id_name(), MemSize); |
46 | |
47 | interprocess_semaphore *my_sem = shm.construct<interprocess_semaphore>(name: "MySem")(0U); |
48 | |
49 | //Launch child process |
50 | std::string s; |
51 | #ifdef BOOST_INTERPROCESS_WINDOWS |
52 | s += "START /B "; |
53 | #endif |
54 | s += argv[0]; |
55 | s += " child "; |
56 | s += test::get_process_id_name(); |
57 | #ifndef BOOST_INTERPROCESS_WINDOWS |
58 | s += " &"; |
59 | #endif |
60 | if(0 != std::system(command: s.c_str())) |
61 | return 1; |
62 | |
63 | //Wait for the other process |
64 | my_sem->wait(); |
65 | |
66 | for (unsigned i = 0; i != 10000; ++i) { |
67 | MyList *mylist = shm.construct<MyList>(name: "MyList", tag: std::nothrow) |
68 | (shm.get_segment_manager()); |
69 | if(mylist){ |
70 | shm.destroy_ptr(ptr: mylist); |
71 | } |
72 | } |
73 | |
74 | //Wait for the other process |
75 | my_sem->wait(); |
76 | } |
77 | else{ |
78 | managed_shared_memory shm (open_only, argv[2]); |
79 | |
80 | interprocess_semaphore *my_sem = shm.find<interprocess_semaphore>(name: "MySem").first; |
81 | if (!my_sem) |
82 | return 1; |
83 | |
84 | my_sem->post(); |
85 | |
86 | for (unsigned i = 0; i != 10000; ++i) { |
87 | MyList *mylist = shm.construct<MyList>(name: "MyList", tag: std::nothrow) |
88 | (shm.get_segment_manager()); |
89 | |
90 | if(mylist){ |
91 | shm.destroy_ptr(ptr: mylist); |
92 | } |
93 | } |
94 | |
95 | my_sem->post(); |
96 | } |
97 | } |
98 | BOOST_CATCH(interprocess_exception &e){ |
99 | std::cerr << p_or_c << " -> interprocess_exception::what(): "<< e.what() |
100 | << " native error: "<< e.get_native_error() |
101 | << " error code: "<< e.get_error_code() << '\n'; |
102 | return 2; |
103 | } |
104 | BOOST_CATCH(std::exception &e){ |
105 | std::cerr << p_or_c << " -> std::exception::what(): "<< e.what() << '\n'; |
106 | return 3; |
107 | } |
108 | BOOST_CATCH_END |
109 | |
110 | std::cerr << p_or_c << " -> Normal termination\n"; |
111 | |
112 | return 0; |
113 | } |
114 | |
115 |