Ticket #5548: shm.cpp

File shm.cpp, 4.4 KB (added by habdank@…, 11 years ago)
Line 
1//
2// Purpose: Play arround with shared memory and the permissions to allocate it
3//
4
5#include <sys/shm.h> // shmget,...
6#include <iostream>
7#include <string>
8#include <cerrno> // errno
9#include <cstring> // strerror
10#include <cstdlib> // system
11
12#include <boost/cstdint.hpp>
13#include <boost/lexical_cast.hpp>
14#include <boost/interprocess/managed_shared_memory.hpp>
15
16static const int invalid_shm_id = -1;
17static const int invalid_shm_pointer = -1;
18
19static const int shm_key = 0x12345;
20static const int shm_size = 0x1000;
21static const std::string shm_key_for_boost =
22 boost::lexical_cast<std::string>(shm_key);
23
24static const int shm_boost_margin = 0x100;
25
26
27boost::uint8_t * shm_create_unix(int & shm_id)
28{
29 //
30 // create global shared memory and get an id of it
31 // (identified by the given key)
32 //
33 shm_id = shmget(shm_key,
34 shm_size,
35 0600 | IPC_CREAT | IPC_EXCL);
36
37 if (shm_id == invalid_shm_id)
38 {
39 std::cerr << "Could not get global shared memory for key="
40 << shm_key
41 << ": " << strerror(errno)
42 << std::endl;
43 return 0;
44 }
45
46 //
47 // attach the global shared memory
48 // (associated with the given id, not the key)
49 //
50 boost::uint8_t * shm =
51 static_cast<boost::uint8_t *>(shmat(shm_id,
52 static_cast<void*>(0),
53 0));
54
55 if (shm == reinterpret_cast<void *>(invalid_shm_pointer))
56 {
57 std::cerr << "Could not attach global shared memory for id="
58 << boost::lexical_cast<std::string>(shm_id)
59 << ", key="
60 << boost::lexical_cast<std::string>(shm_key)
61 << ": " << strerror(errno)
62 << std::endl;
63 return 0;
64 }
65
66 return shm;
67}
68
69void shm_free_unix(boost::uint8_t * shm, int shm_id)
70{
71 int ret = shmdt(shm);
72
73 if (ret == -1)
74 {
75 std::cerr << "Detaching of shared memory (0x"
76 << std::hex << shm << std::dec
77 << ") failed. id=" << shm_id
78 << ": " << strerror(errno)
79 << std::endl;
80 return;
81 }
82
83 ret = shmctl(shm_id, IPC_RMID, NULL);
84
85 if (ret != 0)
86 {
87 std::cerr << "Deleting of shared memory failed. id="
88 << boost::lexical_cast<std::string>(shm_id)
89 << ": " << strerror(errno)
90 << std::endl;
91 }
92}
93
94boost::uint8_t * shm_create_boost()
95{
96 using namespace boost::interprocess;
97
98 //A special shared memory from which we are
99 //able to allocate raw memory buffers.
100 //First remove any old shared memory of the same name, create
101 //the shared memory segment and initialize needed resources
102 shared_memory_object::remove(shm_key_for_boost.c_str());
103
104 void * shm = 0;
105
106 try
107 {
108 // boost also needs some private space in the shared memory
109 managed_shared_memory segment(create_only,
110 shm_key_for_boost.c_str(),
111 shm_size+shm_boost_margin);
112
113 //Allocate a portion of the segment
114 shm = segment.allocate(shm_size);
115 }
116 catch(...)
117 {
118 shared_memory_object::remove(shm_key_for_boost.c_str());
119 throw;
120 }
121
122 return static_cast<boost::uint8_t *>(shm);
123}
124
125void shm_free_boost(boost::uint8_t * shm)
126{
127 using namespace boost::interprocess;
128
129 try
130 {
131 managed_shared_memory segment(open_only,
132 shm_key_for_boost.c_str());
133
134 segment.deallocate(shm);
135 }
136 catch(...)
137 {
138 shared_memory_object::remove(shm_key_for_boost.c_str());
139 throw;
140 }
141
142 shared_memory_object::remove(shm_key_for_boost.c_str());
143}
144
145int main(int argc, char * argv[])
146{
147 if (argc <= 1)
148 {
149 std::cout << "unix way:" << std::endl;
150
151 int shm_id = invalid_shm_id;
152
153 boost::uint8_t * const shm = shm_create_unix(shm_id);
154
155 std::cout << "Got shm=" << static_cast<void *>(shm) << std::endl;
156
157 system("ipcs -m");
158
159 shm_free_unix(shm, shm_id);
160 }
161 else
162 {
163 std::cout << "Boost way:" << std::endl;
164
165 boost::uint8_t * const shm = shm_create_boost();
166
167 std::cout << "Got shm=" << static_cast<void *>(shm) << std::endl;
168
169 system("ipcs -m");
170
171 shm_free_boost(shm);
172 }
173
174 return 0;
175}