Directory: | ./ |
---|---|
File: | include/shared_memory/shared_memory.hpp |
Date: | 2022-06-30 06:29:57 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 28 | 33 | 84.8% |
Branches: | 18 | 28 | 64.3% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * @file shared_memory.hpp | ||
3 | * @author Vincent Berenz | ||
4 | * @author Maximilien Naveau (maximilien.naveau@gmail.com) | ||
5 | * @license License BSD-3-Clause | ||
6 | * @copyright Copyright (c) 2019, New York University and Max Planck | ||
7 | * Gesellschaft. | ||
8 | * @date 2019-05-22 | ||
9 | * | ||
10 | * @brief This file declares some function that encapsulate the use of the | ||
11 | * shared memory using the boost::interprocess package. usage: see demos and | ||
12 | * unit tests and documentation | ||
13 | */ | ||
14 | |||
15 | #pragma once | ||
16 | |||
17 | #ifndef SHARED_MEMORY_HPP | ||
18 | #define SHARED_MEMORY_HPP | ||
19 | |||
20 | #include <chrono> | ||
21 | #include <iostream> | ||
22 | #include <map> | ||
23 | #include <mutex> | ||
24 | #include <string> | ||
25 | #include <vector> | ||
26 | |||
27 | #include <Eigen/Dense> | ||
28 | |||
29 | #include <boost/interprocess/allocators/allocator.hpp> | ||
30 | #include <boost/interprocess/containers/deque.hpp> | ||
31 | #include <boost/interprocess/containers/string.hpp> | ||
32 | #include <boost/interprocess/containers/vector.hpp> | ||
33 | #include <boost/interprocess/managed_shared_memory.hpp> | ||
34 | |||
35 | #include "shared_memory/exceptions.hpp" | ||
36 | #include "shared_memory/segment_info.hpp" | ||
37 | #include "shared_memory/serializer.hpp" | ||
38 | |||
39 | #define DEFAULT_SHARED_MEMORY_SIZE 65536 | ||
40 | #define MAP_STRING_KEY_SEPARATOR ';' | ||
41 | |||
42 | // cool doc: | ||
43 | // https://theboostcpplibraries.com/boost.interprocess-managed-shared-memory | ||
44 | // https://www.boost.org/doc/libs/1_63_0/doc/html/interprocess/quick_guide.html | ||
45 | |||
46 | /** | ||
47 | * All templated types in this namespaces are elementary types: | ||
48 | * int, double, float, char*, ... | ||
49 | */ | ||
50 | namespace shared_memory | ||
51 | { | ||
52 | /** | ||
53 | * @brief sets the size of the segments that will be newly | ||
54 | * created via the set methods. | ||
55 | * Until this function is called, segments are created | ||
56 | * with a size of 65536 bytes. | ||
57 | * This function is not interprocess : it will set | ||
58 | * the size of segments created in the current process | ||
59 | * @param multiplier_1025 the size of create segment | ||
60 | * will be multiplier_1025 * 1025 bytes (because memory | ||
61 | * segment sizes have to be a multiple of 1025) | ||
62 | */ | ||
63 | void set_segment_sizes(uint multiplier_1025); | ||
64 | |||
65 | /** | ||
66 | * @brief set the size of segment newly | ||
67 | * created to the default size value of 65536 | ||
68 | */ | ||
69 | void set_default_segment_sizes(); | ||
70 | |||
71 | /*********************** | ||
72 | * Typdef declarations * | ||
73 | ***********************/ | ||
74 | |||
75 | /** | ||
76 | * @brief ShmObjects typedef is a simple renaming that ease the for loop | ||
77 | * writting. | ||
78 | */ | ||
79 | typedef std::map<std::string, std::pair<void*, std::size_t>> ShmObjects; | ||
80 | |||
81 | /** | ||
82 | * @brief ShmTypeHelper is a small struct that allow the definition of | ||
83 | * templated typedef. | ||
84 | */ | ||
85 | template <typename ElemType> | ||
86 | struct ShmTypeHelper | ||
87 | { | ||
88 | /** | ||
89 | * @brief ShmemAllocator typedef allows to create std::allocator with the | ||
90 | * boost interprocess library. | ||
91 | */ | ||
92 | typedef boost::interprocess::allocator< | ||
93 | ElemType, | ||
94 | boost::interprocess::managed_shared_memory::segment_manager> | ||
95 | ElemTypeAllocator; | ||
96 | |||
97 | typedef boost::container::deque<ElemType, | ||
98 | ShmTypeHelper<ElemType>::ElemTypeAllocator> | ||
99 | ShmDeque; | ||
100 | |||
101 | typedef boost::container::vector<ElemType, | ||
102 | ShmTypeHelper<ElemType>::ElemTypeAllocator> | ||
103 | ShmVector; | ||
104 | }; | ||
105 | |||
106 | /** | ||
107 | * @brief Create a char allocator to ease the creation of strings | ||
108 | */ | ||
109 | typedef ShmTypeHelper<char>::ElemTypeAllocator ShmCharAllocator; | ||
110 | |||
111 | /** | ||
112 | * @brief Create a basic_string type for the Shared Memory | ||
113 | */ | ||
114 | typedef std::basic_string<char, std::char_traits<char>, ShmCharAllocator> | ||
115 | ShmString; | ||
116 | |||
117 | /************************************************ | ||
118 | * Declaration of the SharedMemorySegment class * | ||
119 | ************************************************/ | ||
120 | |||
121 | /** | ||
122 | * @brief The SharedMemorySegment contains the pointers of the shared objects | ||
123 | * in on shared memrory segment | ||
124 | * | ||
125 | * We use unamed mutext (interprocess_mutex) and unamed condition variables | ||
126 | * (interprocess_condition) to be able to instanciate them with classic | ||
127 | * pointers | ||
128 | */ | ||
129 | class SharedMemorySegment | ||
130 | { | ||
131 | public: | ||
132 | /** | ||
133 | * @brief SharedMemorySegment constructor. | ||
134 | */ | ||
135 | SharedMemorySegment(std::string segment_id, | ||
136 | bool clear_upon_destruction, | ||
137 | bool create); | ||
138 | |||
139 | /** | ||
140 | * @brief SharedMemorySegment destructor. | ||
141 | */ | ||
142 | 48 | ~SharedMemorySegment() | |
143 | 48 | { | |
144 | 48 | } | |
145 | |||
146 | /** | ||
147 | * @brief clear_memory free the shared memory | ||
148 | */ | ||
149 | void clear_memory(); | ||
150 | |||
151 | /** | ||
152 | * @brief get_object registers the object in the current struc and in the | ||
153 | * shared memory once only. And returns the pointer to the object and its | ||
154 | * size. The size will be 1 for simple type and could greater to one for | ||
155 | * arrays. | ||
156 | * @param[in] object_id: the name of the object in the shared memory. | ||
157 | * @param[in][out] get_: the reference to the fetched object. | ||
158 | */ | ||
159 | template <typename ElemType> | ||
160 | void get_object(const std::string& object_id, | ||
161 | std::pair<ElemType*, std::size_t>& get_); | ||
162 | |||
163 | /** | ||
164 | * @brief get_object registers the object in the current struc and in the | ||
165 | * shared memory once only. And returns the pointer to the object and its | ||
166 | * size. The size will be 1 for simple type and could greater to one for | ||
167 | * arrays. | ||
168 | * @param[in] object_id: the name of the object in the shared memory. | ||
169 | * @param[in][out] get_: the reference to the fetched object. | ||
170 | */ | ||
171 | void get_object(const std::string& object_id, std::string& get_); | ||
172 | |||
173 | /** | ||
174 | * @brief set_object registers the object in the current struc and in the | ||
175 | * shared memory once only. And returns the pointer to the object and its | ||
176 | * size. The size will be 1 for simple type and could greater to one for | ||
177 | * arrays. | ||
178 | * @param[in] object_id: the name of the object in the shared memory. | ||
179 | * @param[in] set_: the reference to the fetched object. | ||
180 | */ | ||
181 | template <typename ElemType> | ||
182 | void set_object(const std::string& object_id, | ||
183 | const std::pair<const ElemType*, std::size_t>& set_); | ||
184 | |||
185 | /** | ||
186 | * @brief register_object registers the object in the segment uniquely. | ||
187 | * @param object_id is the name of the object to register. | ||
188 | * @param obj_ is the object to be registered. | ||
189 | * @return true of a new object has been registered | ||
190 | */ | ||
191 | template <typename ElemType> | ||
192 | bool register_object(const std::string& object_id, | ||
193 | const std::pair<ElemType*, std::size_t>& obj_); | ||
194 | |||
195 | /** | ||
196 | * @brief register_object_read_only registers the object in the segment | ||
197 | * uniquely. | ||
198 | * @param object_id is the name of the object to register | ||
199 | * @param obj_ is the object to be registered | ||
200 | * @return true of a new object has been registered | ||
201 | */ | ||
202 | template <typename ElemType> | ||
203 | bool register_object_read_only(const std::string& object_id); | ||
204 | |||
205 | /** | ||
206 | * @brief delete_object delete and object from the shared memory. | ||
207 | * @param[in] object_id: the name of the object in the shared memory. | ||
208 | */ | ||
209 | template <typename ElemType> | ||
210 | void delete_object(const std::string& object_id); | ||
211 | |||
212 | /** | ||
213 | * @brief mutex_ this mutex secure ALL the shared memory. | ||
214 | */ | ||
215 | boost::interprocess::interprocess_mutex* mutex_; | ||
216 | // boost::interprocess::named_mutex named_mtx_; | ||
217 | |||
218 | /** | ||
219 | * @brief create_mutex small factory that allow to make sure that the mutex | ||
220 | * is created. | ||
221 | */ | ||
222 | 77 | void create_mutex() | |
223 | { | ||
224 | 77 | mutex_ = | |
225 | segment_manager_ | ||
226 |
1/2✓ Branch 1 taken 77 times.
✗ Branch 2 not taken.
|
154 | .find_or_construct<boost::interprocess::interprocess_mutex>( |
227 |
1/2✓ Branch 2 taken 77 times.
✗ Branch 3 not taken.
|
231 | "mutex_")(); |
228 | 77 | } | |
229 | |||
230 | /** | ||
231 | * @brief destroy_mutex small destructor of the mutext to make sure that it | ||
232 | * is unlock at critical time. | ||
233 | */ | ||
234 | ✗ | void destroy_mutex() | |
235 | { | ||
236 | ✗ | segment_manager_.destroy<boost::interprocess::interprocess_mutex>( | |
237 | "mutex_"); | ||
238 | ✗ | mutex_ = nullptr; | |
239 | } | ||
240 | |||
241 | /** | ||
242 | * @brief is_object_registered used to check if the object has been | ||
243 | * registered or not. | ||
244 | * @param[in] object_id: the name of the object in the shared memory. | ||
245 | * @return true if it has been registered | ||
246 | */ | ||
247 | 18948 | bool is_object_registered(const std::string& object_id) | |
248 | { | ||
249 |
3/4✓ Branch 1 taken 18865 times.
✓ Branch 2 taken 83 times.
✓ Branch 3 taken 18865 times.
✗ Branch 4 not taken.
|
37813 | return !(objects_.count(object_id) == 0 || |
250 | 37813 | objects_[object_id].first == nullptr); | |
251 | } | ||
252 | |||
253 | /** | ||
254 | * @brief set_clear_upon_destruction is a standard setter | ||
255 | * @param[in] clear_upon_destruction is the value to set | ||
256 | */ | ||
257 | 18978 | void set_clear_upon_destruction(const bool clear_upon_destruction) | |
258 | { | ||
259 | 18978 | clear_upon_destruction_ = clear_upon_destruction; | |
260 | 18978 | } | |
261 | |||
262 | /** | ||
263 | * @brief get_segment_id is a standard getter | ||
264 | * @return the segment name | ||
265 | */ | ||
266 | ✗ | const std::string& get_segment_id() | |
267 | { | ||
268 | ✗ | return segment_id_; | |
269 | } | ||
270 | |||
271 | /** | ||
272 | * @brief performs introspection on the segment | ||
273 | * and return related information | ||
274 | */ | ||
275 | // dev notes: boost api does not allow for this method | ||
276 | // to be const | ||
277 | 2 | SegmentInfo get_info() | |
278 | { | ||
279 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | SegmentInfo si(segment_manager_); |
280 | 2 | return si; | |
281 | } | ||
282 | |||
283 | private: | ||
284 | /** | ||
285 | * @brief shm_segment is the boost object that manages the shared memory | ||
286 | * segment | ||
287 | */ | ||
288 | boost::interprocess::managed_shared_memory segment_manager_; | ||
289 | |||
290 | /** | ||
291 | * @brief objects_ are all the data stored in the segment. WARNING here we | ||
292 | * use void* so the use of the set and get functions is the RESPONSABILITY | ||
293 | * of the user. | ||
294 | * | ||
295 | * The user is to use the SAME type when calling set and get using the | ||
296 | * shared memory | ||
297 | */ | ||
298 | ShmObjects objects_; | ||
299 | |||
300 | /** | ||
301 | * @brief segment_id_ is the name of the segment inside the shared memory | ||
302 | */ | ||
303 | std::string segment_id_; | ||
304 | |||
305 | /** | ||
306 | * @brief clear_upon_destruction_ flag decides if the segment should be | ||
307 | * cleared upon destruction. | ||
308 | * | ||
309 | * Usage: typically only one process should set this flag to true. | ||
310 | */ | ||
311 | bool clear_upon_destruction_; | ||
312 | |||
313 | int ravioli_; | ||
314 | }; | ||
315 | |||
316 | /************************************************** | ||
317 | * Declaration of all segment management function * | ||
318 | **************************************************/ | ||
319 | |||
320 | /** | ||
321 | * @brief get_segment creates or give back a pointer to a SharedMemorySegment | ||
322 | * object. | ||
323 | * @param segment_id is the name of the shared memory segment. | ||
324 | */ | ||
325 | SharedMemorySegment& get_segment(const std::string& segment_id, | ||
326 | const bool clear_upon_destruction = false, | ||
327 | const bool create = true); | ||
328 | |||
329 | /** | ||
330 | * @brief performs introspection on the segment | ||
331 | * and return related information. If the segment does not | ||
332 | * exists, creates it first. | ||
333 | */ | ||
334 | SegmentInfo get_segment_info(const std::string& segment_id); | ||
335 | |||
336 | /** | ||
337 | * @brief returns true if a segment exists under this id | ||
338 | * @param segment_id is the name of the shared memory segment. | ||
339 | */ | ||
340 | bool segment_exists(const std::string& segment_id); | ||
341 | |||
342 | /** | ||
343 | * @brief delete_segment deletes the segment of existing shared memory. | ||
344 | * it makes sure that all element created in it is destroyed first. | ||
345 | * (is this needed? I do not know.) | ||
346 | * @param segment_id is the name of the shared memory segment. | ||
347 | */ | ||
348 | void delete_segment(const std::string& segment_id); | ||
349 | |||
350 | /** | ||
351 | * @brief delete_all_segment delete all mapping to the shared memory used | ||
352 | * during the current process | ||
353 | */ | ||
354 | void delete_all_segments(); | ||
355 | |||
356 | /** | ||
357 | * @brief alias for delete_all_segments (for retro compatibility) | ||
358 | */ | ||
359 | void delete_all_segment(); | ||
360 | |||
361 | /** | ||
362 | * @brief delete_object deletes a particular object in the shared memory | ||
363 | * segment | ||
364 | * @param[in] segment_id is the name of the shared memory segment. | ||
365 | * @return true if everything went fine. | ||
366 | */ | ||
367 | template <typename ElemType> | ||
368 | bool delete_object(const std::string& segment_id, const std::string& object_id); | ||
369 | |||
370 | /** | ||
371 | * @brief get_sgement_mutex aquiere a reference to the semgent global mutex. | ||
372 | * @param[in] segment_id is the name of the shared memory segment. | ||
373 | * @return a reference to a boost mutex | ||
374 | */ | ||
375 | boost::interprocess::interprocess_mutex& get_segment_mutex( | ||
376 | const std::string segment_id); | ||
377 | |||
378 | /** | ||
379 | * @brief clear_shared_memory_segment destroys the shared memory | ||
380 | * @param[in] segment_id is the name of the shared memory segment. | ||
381 | */ | ||
382 | void clear_shared_memory(const std::string& segment_id); | ||
383 | |||
384 | /************************************ | ||
385 | * Declaration of all set functions * | ||
386 | ************************************/ | ||
387 | |||
388 | /** | ||
389 | * @brief set instanciates or get pointer to any elementary types in the | ||
390 | * shared memory. | ||
391 | * | ||
392 | * All set functions make sure that the pointer is uniquely created to avoid | ||
393 | * useless computation time consumption. | ||
394 | * | ||
395 | * @param[in] segment_id is the name of the shared memory segment. | ||
396 | * @param[in] object_id is the name of the shared memory object to set. | ||
397 | * @param[in] set_ is the string to be created in the shared memory | ||
398 | */ | ||
399 | template <typename ElemType> | ||
400 | void set(const std::string& segment_id, | ||
401 | const std::string& object_id, | ||
402 | const ElemType& set_); | ||
403 | |||
404 | /** | ||
405 | * @brief set instanciates or get pointer to a fixed sized | ||
406 | * array of the templated type "T" in the shared memory. | ||
407 | * | ||
408 | * All set functions make sure that the pointer is uniquely created to avoid | ||
409 | * useless computation time consumption. | ||
410 | * | ||
411 | * @param[in] segment_id is the name of the shared memory segment. | ||
412 | * @param[in] object_id is the name of the shared memory object to set. | ||
413 | * @param[in] set_ is the pointer to the array of objects to set in the | ||
414 | * memory. | ||
415 | * @param[in] size is the array size. | ||
416 | */ | ||
417 | template <typename ElemType> | ||
418 | void set(const std::string& segment_id, | ||
419 | const std::string& object_id, | ||
420 | const ElemType* set_, | ||
421 | const std::size_t size); | ||
422 | |||
423 | /** | ||
424 | * @brief set instanciates or get pointer to a string in the shared memory. | ||
425 | * | ||
426 | * All set functions make sure that the pointer is uniquely created to avoid | ||
427 | * useless computation time consumption. | ||
428 | * | ||
429 | * @param[in] segment_id is the name of the shared memory segment. | ||
430 | * @param[in] object_id is the name of the shared memory object to set. | ||
431 | * @param[in] set_ is the string to be created in the shared memory | ||
432 | */ | ||
433 | void set(const std::string& segment_id, | ||
434 | const std::string& object_id, | ||
435 | const std::string& set_); | ||
436 | |||
437 | /** | ||
438 | * @brief set instanciates or get pointer to a std::vector<ElemType> | ||
439 | * in the shared memory. | ||
440 | * This will translated as a fixed sized array in the shared memory | ||
441 | * | ||
442 | * All set functions make sure that the pointer is uniquely created to avoid | ||
443 | * useless computation time consumption. | ||
444 | * | ||
445 | * @param[in] segment_id is the name of the shared memory segment. | ||
446 | * @param[in] object_id is the name of the shared memory object to set. | ||
447 | * @param[in] set_ is the string to be created in the shared memory | ||
448 | */ | ||
449 | template <typename ElemType> | ||
450 | void set(const std::string& segment_id, | ||
451 | const std::string& object_id, | ||
452 | const std::vector<ElemType>& set_); | ||
453 | |||
454 | /** | ||
455 | * @brief set instanciates or get pointer to a | ||
456 | * Eigen::Matrix<ElemType, Eigen::Dynamic, 1> in the shared memory. | ||
457 | * This will translated as a fixed sized array in the shared memory | ||
458 | * | ||
459 | * All set functions make sure that the pointer is uniquely created to avoid | ||
460 | * useless computation time consumption. | ||
461 | * | ||
462 | * @param[in] segment_id is the name of the shared memory segment. | ||
463 | * @param[in] object_id is the name of the shared memory object to set. | ||
464 | * @param[in] set_ is the string to be created in the shared memory | ||
465 | */ | ||
466 | template <typename ElemType> | ||
467 | void set(const std::string& segment_id, | ||
468 | const std::string& object_id, | ||
469 | const Eigen::Matrix<ElemType, Eigen::Dynamic, 1>& set_); | ||
470 | |||
471 | /** | ||
472 | * @brief set instanciates or get pointer to a | ||
473 | * std::pair<FirstType, SecondType> in the shared memory. | ||
474 | * This is very usefull to dump maps in the shared memory | ||
475 | * | ||
476 | * All set functions make sure that the pointer is uniquely created to avoid | ||
477 | * useless computation time consumption. | ||
478 | * | ||
479 | * @param[in] segment_id is the name of the shared memory segment. | ||
480 | * @param[in] object_id is the name of the shared memory object to set. | ||
481 | * @param[in] set_ is the string to be created in the shared memory | ||
482 | */ | ||
483 | template <typename FirstType, typename SecondType> | ||
484 | void set(const std::string& segment_id, | ||
485 | const std::string& object_id, | ||
486 | const std::pair<FirstType, SecondType>& set_); | ||
487 | |||
488 | /** | ||
489 | * @brief set instanciates or get pointer to a std::vector<ElemType> or an | ||
490 | * Eigen::Matrix<ElemType, any, any> in the shared memory. | ||
491 | * This will translated as a fixed sized array in the shared memory | ||
492 | * | ||
493 | * All set functions make sure that the pointer is uniquely created to avoid | ||
494 | * useless computation time consumption. | ||
495 | * | ||
496 | * @param[in] segment_id is the name of the shared memory segment. | ||
497 | * @param[in] object_id is the name of the shared memory object to set. | ||
498 | * @param[in] set_ is the string to be created in the shared memory | ||
499 | */ | ||
500 | template <typename KeyType, typename ValueType> | ||
501 | void set(const std::string& segment_id, | ||
502 | const std::string& object_id, | ||
503 | const std::map<KeyType, ValueType>& set_); | ||
504 | |||
505 | /************************************ | ||
506 | * Declaration of all get functions * | ||
507 | ************************************/ | ||
508 | |||
509 | /** | ||
510 | * @brief get gets a pointer to any elementary types in the | ||
511 | * shared memory. | ||
512 | * | ||
513 | * All set functions make sure that the pointer is uniquely created to avoid | ||
514 | * useless computation time consumption. | ||
515 | * | ||
516 | * @param[in] segment_id is the name of the shared memory segment. | ||
517 | * @param[in] object_id is the name of the shared memory object to set. | ||
518 | * @param[in] get_ is the string to be created in the shared memory | ||
519 | */ | ||
520 | template <typename ElemType> | ||
521 | void get(const std::string& segment_id, | ||
522 | const std::string& object_id, | ||
523 | ElemType& get_, | ||
524 | bool create = true); | ||
525 | |||
526 | /** | ||
527 | * @brief get gets a pointer to a fixed sized | ||
528 | * array of the templated type "T" in the shared memory. | ||
529 | * | ||
530 | * All set functions make sure that the pointer is uniquely created to avoid | ||
531 | * useless computation time consumption. | ||
532 | * | ||
533 | * @param[in] segment_id is the name of the shared memory segment. | ||
534 | * @param[in] object_id is the name of the shared memory object to set. | ||
535 | * @param[in] get_ is the pointer to the array of objects to set in the | ||
536 | * memory. | ||
537 | * @param[in] size is the array size. | ||
538 | * @param[in] create : if false, raise a Non_existing_segment_exception | ||
539 | if the segment does not already exist | ||
540 | */ | ||
541 | template <typename ElemType> | ||
542 | void get(const std::string& segment_id, | ||
543 | const std::string& object_id, | ||
544 | ElemType* get_, | ||
545 | const std::size_t expected_size, | ||
546 | bool create = true); | ||
547 | |||
548 | /** | ||
549 | * @brief get gets a pointer to a string in the shared memory. | ||
550 | * | ||
551 | * All set functions make sure that the pointer is uniquely created to avoid | ||
552 | * useless computation time consumption. | ||
553 | * | ||
554 | * @param[in] segment_id is the name of the shared memory segment. | ||
555 | * @param[in] object_id is the name of the shared memory object to set. | ||
556 | * @param[in] get_ is the string to be created in the shared memory | ||
557 | * @param[in] create : if false, raise a Non_existing_segment_exception | ||
558 | if the segment does not already exist | ||
559 | */ | ||
560 | void get(const std::string& segment_id, | ||
561 | const std::string& object_id, | ||
562 | std::string& get_, | ||
563 | bool create = true); | ||
564 | |||
565 | /** | ||
566 | * @brief get gets a pointer to a std::vector<ElemType> | ||
567 | * in the shared memory. | ||
568 | * This will translated as a fixed sized array in the shared memory | ||
569 | * | ||
570 | * All set functions make sure that the pointer is uniquely created to avoid | ||
571 | * useless computation time consumption. | ||
572 | * | ||
573 | * @param[in] segment_id is the name of the shared memory segment. | ||
574 | * @param[in] object_id is the name of the shared memory object to set. | ||
575 | * @param[in] set_ is the string to be created in the shared memory | ||
576 | * @param[in] create : if false, raise a Non_existing_segment_exception | ||
577 | if the segment does not already exist | ||
578 | */ | ||
579 | template <typename ElemType> | ||
580 | void get(const std::string& segment_id, | ||
581 | const std::string& object_id, | ||
582 | std::vector<ElemType>& get_, | ||
583 | bool create = true); | ||
584 | |||
585 | /** | ||
586 | * @brief get gets a pointer to a | ||
587 | * Eigen::Matrix<ElemType, Eigen::Dynamic, 1> in the shared memory. | ||
588 | * This will translated as a fixed sized array in the shared memory | ||
589 | * | ||
590 | * All set functions make sure that the pointer is uniquely created to avoid | ||
591 | * useless computation time consumption. | ||
592 | * | ||
593 | * @param[in] segment_id is the name of the shared memory segment. | ||
594 | * @param[in] object_id is the name of the shared memory object to set. | ||
595 | * @param[in] set_ is the string to be created in the shared memory | ||
596 | * @param[in] create : if false, raise a Non_existing_segment_exception | ||
597 | if the segment does not already exist | ||
598 | */ | ||
599 | template <typename ElemType> | ||
600 | void get(const std::string& segment_id, | ||
601 | const std::string& object_id, | ||
602 | Eigen::Matrix<ElemType, Eigen::Dynamic, 1>& get_, | ||
603 | bool create = true); | ||
604 | |||
605 | /** | ||
606 | * @brief get instanciates or get pointer to a | ||
607 | * std::pair<FirstType, SecondType> in the shared memory. | ||
608 | * This is very usefull to dump maps in the shared memory | ||
609 | * | ||
610 | * All set functions make sure that the pointer is uniquely created to avoid | ||
611 | * useless computation time consumption. | ||
612 | * | ||
613 | * @param[in] segment_id is the name of the shared memory segment. | ||
614 | * @param[in] object_id is the name of the shared memory object to set. | ||
615 | * @param[in] get_ is the string to be created in the shared memory | ||
616 | * @param[in] create : if false, raise a Non_existing_segment_exception | ||
617 | if the segment does not already exist | ||
618 | */ | ||
619 | template <typename FirstType, typename SecondType> | ||
620 | void get(const std::string& segment_id, | ||
621 | const std::string& object_id, | ||
622 | std::pair<FirstType, SecondType>& get_, | ||
623 | bool create = true); | ||
624 | |||
625 | /** | ||
626 | * @brief get gets a pointer to a std::vector<ElemType> or an | ||
627 | * Eigen::Matrix<ElemType, any, any> in the shared memory. | ||
628 | * This will translated as a fixed sized array in the shared memory | ||
629 | * | ||
630 | * All set functions make sure that the pointer is uniquely created to avoid | ||
631 | * useless computation time consumption. | ||
632 | * | ||
633 | * @param[in] segment_id is the name of the shared memory segment. | ||
634 | * @param[in] object_id is the name of the shared memory object to set. | ||
635 | * @param[in] get_ is the string to be created in the shared memory | ||
636 | * @param[in] create : if false, raise a Non_existing_segment_exception | ||
637 | if the segment does not already exist | ||
638 | */ | ||
639 | template <typename KeyType, typename ValueType> | ||
640 | void get(const std::string& segment_id, | ||
641 | const std::string& object_id, | ||
642 | std::map<KeyType, ValueType>& get_, | ||
643 | bool create = true); | ||
644 | |||
645 | /** | ||
646 | * @brief Serialize the instance into a string which is | ||
647 | * written in the shared memory. This uses cereal for | ||
648 | * serialization, and Serializable must implement a serialize function, | ||
649 | * see: https://uscilab.github.io/cereal/ | ||
650 | * @param[in] segment_id is the name of the shared memory segment. | ||
651 | * @param[in] object_id is the name of the shared memory object to set. | ||
652 | * @param[in] serializable is the instance to serialize | ||
653 | */ | ||
654 | template <class Serializable> | ||
655 | 2 | void serialize(const std::string& segment, | |
656 | const std::string& object, | ||
657 | const Serializable& serializable) | ||
658 | { | ||
659 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | static Serializer<Serializable> serializer; |
660 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
4 | std::string data = serializer.serialize(serializable); |
661 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | shared_memory::set(segment, object, data); |
662 | 2 | } | |
663 | |||
664 | /** | ||
665 | * @brief Read from the memory a string that is deserialized | ||
666 | * into the passed instance of Serializable. | ||
667 | * This assumes the serialization and writting in the shared | ||
668 | * memory has been performed using the serialize function. | ||
669 | * @param[in] segment_id is the name of the shared memory segment. | ||
670 | * @param[in] object_id is the name of the shared memory object to set. | ||
671 | * @param[in] serializable is the instance in which the string | ||
672 | * will be deserialized | ||
673 | */ | ||
674 | template <class Serializable> | ||
675 | 2 | void deserialize(const std::string& segment, | |
676 | const std::string& object, | ||
677 | Serializable& serializable) | ||
678 | { | ||
679 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | static Serializer<Serializable> serializer; |
680 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | static std::string data; |
681 | 2 | shared_memory::get(segment, object, data); | |
682 | 2 | serializer.deserialize(data, serializable); | |
683 | 2 | } | |
684 | |||
685 | /** | ||
686 | * @brief if verbose mode set to true (starting default is false), | ||
687 | * informaton about newly created objects will be displayed in the | ||
688 | * terminal. Call to this function will change the verbose mode | ||
689 | * only for the current process. | ||
690 | */ | ||
691 | void set_verbose(bool mode); | ||
692 | |||
693 | /** | ||
694 | * @brief wait until the segment is created either via | ||
695 | * call to a get or set function. | ||
696 | * @param[in] segment_id is the name of the shared memory segment. | ||
697 | * @param[in] timeout_ms is a timeout in ms | ||
698 | * @return true if the segment has been created before the timeout | ||
699 | * expired, false otherwise. | ||
700 | */ | ||
701 | bool wait_for_segment(const std::string& segment_id, int timeout_ms = -1); | ||
702 | |||
703 | } // namespace shared_memory | ||
704 | |||
705 | #include <shared_memory/shared_memory.hxx> | ||
706 | |||
707 | #endif // SHARED_MEMORY_HPP | ||
708 |