| Directory: | ./ |
|---|---|
| File: | include/shared_memory/internal/exchange_manager_memory.hxx |
| Date: | 2022-06-30 06:29:57 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 138 | 148 | 93.2% |
| Branches: | 71 | 134 | 53.0% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | template <class Serializable> | ||
| 4 | 22 | Serialized_read<Serializable>::Serialized_read() | |
| 5 | : size_(0), | ||
| 6 | nb_char_read_(0), | ||
| 7 |
1/2✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
|
22 | serializable_size_(Serializer<Serializable>::serializable_size()) |
| 8 | { | ||
| 9 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | values_ = new char[serializable_size_]; |
| 10 | 22 | } | |
| 11 | |||
| 12 | template <class Serializable> | ||
| 13 | 22 | Serialized_read<Serializable>::~Serialized_read() | |
| 14 | { | ||
| 15 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | delete[] values_; |
| 16 | 22 | } | |
| 17 | |||
| 18 | template <class Serializable> | ||
| 19 | 28000 | void Serialized_read<Serializable>::set(char value) | |
| 20 | { | ||
| 21 | 28000 | size_++; | |
| 22 | 28000 | buffer_.push_back(value); | |
| 23 | 28000 | } | |
| 24 | |||
| 25 | template <class Serializable> | ||
| 26 | 1017 | bool Serialized_read<Serializable>::read(Serializable &serializable) | |
| 27 | { | ||
| 28 |
2/2✓ Branch 0 taken 1000 times.
✓ Branch 1 taken 17 times.
|
1017 | if (size_ >= serializable_size_) |
| 29 | { | ||
| 30 |
2/2✓ Branch 0 taken 28000 times.
✓ Branch 1 taken 1000 times.
|
29000 | for (int i = 0; i < serializable_size_; i++) |
| 31 | { | ||
| 32 | 28000 | values_[i] = buffer_.front(); | |
| 33 | 28000 | buffer_.pop_front(); | |
| 34 | 28000 | size_--; | |
| 35 | 28000 | nb_char_read_++; | |
| 36 | } | ||
| 37 |
2/4✓ Branch 2 taken 1000 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1000 times.
✗ Branch 6 not taken.
|
1000 | serializer_.deserialize(std::string(values_, serializable_size_), |
| 38 | serializable); | ||
| 39 | 1000 | return true; | |
| 40 | } | ||
| 41 | 17 | return false; | |
| 42 | } | ||
| 43 | |||
| 44 | template <class Serializable> | ||
| 45 | void Serialized_read<Serializable>::reset_nb_char_read() | ||
| 46 | { | ||
| 47 | nb_char_read_ = 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | template <class Serializable> | ||
| 51 | int Serialized_read<Serializable>::nb_char_read() | ||
| 52 | { | ||
| 53 | return nb_char_read_; | ||
| 54 | } | ||
| 55 | |||
| 56 | template <class Serializable> | ||
| 57 | 22 | Serialized_write<Serializable>::Serialized_write() | |
| 58 | : nb_char_written_(0), | ||
| 59 |
1/2✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
|
22 | serializable_size_(Serializer<Serializable>::serializable_size()) |
| 60 | { | ||
| 61 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | values_ = new char[serializable_size_]; |
| 62 | 22 | } | |
| 63 | |||
| 64 | template <class Serializable> | ||
| 65 | 22 | Serialized_write<Serializable>::~Serialized_write() | |
| 66 | { | ||
| 67 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | delete[] values_; |
| 68 | 22 | } | |
| 69 | |||
| 70 | template <class Serializable> | ||
| 71 | int Serialized_write<Serializable>::nb_char_written() | ||
| 72 | { | ||
| 73 | return nb_char_written_; | ||
| 74 | } | ||
| 75 | |||
| 76 | template <class Serializable> | ||
| 77 | void Serialized_write<Serializable>::reset_nb_char_written() | ||
| 78 | { | ||
| 79 | nb_char_written_ = 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | template <class Serializable> | ||
| 83 | 29000 | bool Serialized_write<Serializable>::empty() | |
| 84 | { | ||
| 85 | 29000 | return buffer_.empty(); | |
| 86 | } | ||
| 87 | |||
| 88 | template <class Serializable> | ||
| 89 | 28000 | char Serialized_write<Serializable>::front() | |
| 90 | { | ||
| 91 | 28000 | char value = buffer_.front(); | |
| 92 | 28000 | return value; | |
| 93 | } | ||
| 94 | |||
| 95 | template <class Serializable> | ||
| 96 | 28000 | void Serialized_write<Serializable>::pop() | |
| 97 | { | ||
| 98 | 28000 | buffer_.pop_front(); | |
| 99 | 28000 | } | |
| 100 | |||
| 101 | template <class Serializable> | ||
| 102 | 1000 | void Serialized_write<Serializable>::write(const Serializable &serializable, | |
| 103 | std::size_t expected_size) | ||
| 104 | { | ||
| 105 | 1000 | const std::string &s = serializer_.serialize(serializable); | |
| 106 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1000 times.
|
1000 | if (s.size() != expected_size) |
| 107 | { | ||
| 108 | throw std::runtime_error( | ||
| 109 | ✗ | "exchange_manager_memory: serialized string of unexpected size\n"); | |
| 110 | } | ||
| 111 |
2/2✓ Branch 3 taken 28000 times.
✓ Branch 4 taken 1000 times.
|
29000 | for (char c : s) |
| 112 | { | ||
| 113 | 28000 | nb_char_written_++; | |
| 114 |
1/2✓ Branch 1 taken 28000 times.
✗ Branch 2 not taken.
|
28000 | buffer_.push_back(c); |
| 115 | } | ||
| 116 | 1000 | } | |
| 117 | |||
| 118 | template <class Serializable, int QUEUE_SIZE> | ||
| 119 | 22 | Exchange_manager_memory<Serializable, QUEUE_SIZE>::Exchange_manager_memory( | |
| 120 | std::string segment_id, std::string object_id) | ||
| 121 | |||
| 122 | : nb_char_read_(0), | ||
| 123 | nb_char_written_(0), | ||
| 124 | segment_(bip::open_or_create, segment_id.c_str(), 100 * 65536), | ||
| 125 | locker_(std::string(segment_id + "_locker").c_str(), false), | ||
| 126 |
9/18✓ Branch 5 taken 22 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 22 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 22 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 22 times.
✗ Branch 17 not taken.
✓ Branch 20 taken 22 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 22 times.
✗ Branch 24 not taken.
✓ Branch 29 taken 22 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 22 times.
✗ Branch 33 not taken.
✓ Branch 35 taken 22 times.
✗ Branch 36 not taken.
|
22 | serializable_size_(Serializer<Serializable>::serializable_size()) |
| 127 | { | ||
| 128 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | object_id_producer_ = object_id + "_producer"; |
| 129 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | object_id_consumer_ = object_id + "_consumer"; |
| 130 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | object_id_status_ = object_id + "_status"; |
| 131 | 22 | produced_ = segment_.find_or_construct<producer_queue>( | |
| 132 |
2/4✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
|
44 | object_id_producer_.c_str())(); |
| 133 | 22 | consumed_ = segment_.find_or_construct<consumer_queue>( | |
| 134 |
2/4✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
|
44 | object_id_consumer_.c_str())(); |
| 135 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | segment_id_ = segment_id; |
| 136 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | values_ = new char[serializable_size_]; |
| 137 | |||
| 138 | // dev note: not sure what is happening, but the queues | ||
| 139 | // (produced_ and consumed_) are not defined empty, despite | ||
| 140 | // their empty() function returning true (i.e. items can | ||
| 141 | // be poped from them). This results to various undefined behavior. | ||
| 142 | // This function removes all these items from the queues. | ||
| 143 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | weird_purge(); |
| 144 | 22 | } | |
| 145 | |||
| 146 | // in constructor, remove all items from the queue, which | ||
| 147 | // can be poped from the queue despite the queue reporting | ||
| 148 | // being empty (as it should). No idea what is going on. | ||
| 149 | template <class Serializable, int QUEUE_SIZE> | ||
| 150 | 22 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::weird_purge() | |
| 151 | { | ||
| 152 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | lock(); |
| 153 | |||
| 154 | char foo; | ||
| 155 | int foo_; | ||
| 156 | |||
| 157 |
2/4✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
|
22 | while (produced_->empty()) |
| 158 | { | ||
| 159 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | bool poped = produced_->pop(foo); |
| 160 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | if (!poped) |
| 161 | { | ||
| 162 | 22 | break; | |
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 |
2/4✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
|
22 | while (consumed_->empty()) |
| 167 | { | ||
| 168 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | bool poped = consumed_->pop(foo_); |
| 169 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | if (!poped) |
| 170 | { | ||
| 171 | 22 | break; | |
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | unlock(); |
| 176 | 22 | } | |
| 177 | |||
| 178 | template <class Serializable, int QUEUE_SIZE> | ||
| 179 | 22 | Exchange_manager_memory<Serializable, QUEUE_SIZE>::~Exchange_manager_memory() | |
| 180 | { | ||
| 181 | 22 | unlock(); | |
| 182 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | delete[] values_; |
| 183 | 22 | } | |
| 184 | |||
| 185 | template <class Serializable, int QUEUE_SIZE> | ||
| 186 | 33 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::set_status( | |
| 187 | Status status) | ||
| 188 | { | ||
| 189 | 33 | lock(); | |
| 190 |
1/2✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
|
33 | shared_memory::set<int>(segment_id_, object_id_status_, status); |
| 191 | 33 | unlock(); | |
| 192 | 33 | } | |
| 193 | |||
| 194 | template <class Serializable, int QUEUE_SIZE> | ||
| 195 | 1301 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::get_status( | |
| 196 | Status &status) | ||
| 197 | { | ||
| 198 | int r; | ||
| 199 | |||
| 200 |
1/2✓ Branch 1 taken 1301 times.
✗ Branch 2 not taken.
|
1301 | lock(); |
| 201 |
1/2✓ Branch 1 taken 1301 times.
✗ Branch 2 not taken.
|
1301 | shared_memory::get<int>(segment_id_, object_id_status_, r); |
| 202 |
1/2✓ Branch 1 taken 1301 times.
✗ Branch 2 not taken.
|
1301 | unlock(); |
| 203 | |||
| 204 | 1301 | status = static_cast<Status>(r); | |
| 205 | 1301 | } | |
| 206 | |||
| 207 | template <class Serializable, int QUEUE_SIZE> | ||
| 208 | 11 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::clean() | |
| 209 | { | ||
| 210 |
1/2✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
|
11 | Exchange_manager_memory<Serializable, QUEUE_SIZE>::clean_mutex(segment_id_); |
| 211 |
1/2✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
|
11 | Exchange_manager_memory<Serializable, QUEUE_SIZE>::clean_memory( |
| 212 | segment_id_); | ||
| 213 | 11 | } | |
| 214 | |||
| 215 | template <class Serializable, int QUEUE_SIZE> | ||
| 216 | 4395 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::lock() | |
| 217 | { | ||
| 218 | 4395 | locker_.lock(); | |
| 219 | 4395 | } | |
| 220 | |||
| 221 | template <class Serializable, int QUEUE_SIZE> | ||
| 222 | 4417 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::unlock() | |
| 223 | { | ||
| 224 | 4417 | locker_.unlock(); | |
| 225 | 4417 | } | |
| 226 | |||
| 227 | template <class Serializable, int QUEUE_SIZE> | ||
| 228 | 13 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::clean_mutex( | |
| 229 | std::string segment_id) | ||
| 230 | { | ||
| 231 | // mutex destruction called in destructor | ||
| 232 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
13 | shared_memory::Mutex m(segment_id + "_locker", true); |
| 233 | 13 | } | |
| 234 | |||
| 235 | template <class Serializable, int QUEUE_SIZE> | ||
| 236 | 13 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::clean_memory( | |
| 237 | std::string segment_id) | ||
| 238 | { | ||
| 239 | 13 | shared_memory::clear_shared_memory(segment_id); | |
| 240 | 13 | shared_memory::delete_segment(segment_id); | |
| 241 | 13 | } | |
| 242 | |||
| 243 | template <class Serializable, int QUEUE_SIZE> | ||
| 244 | 29017 | bool Exchange_manager_memory<Serializable, QUEUE_SIZE>::read_serialized( | |
| 245 | Serializable &serializable) | ||
| 246 | { | ||
| 247 |
2/2✓ Branch 1 taken 28000 times.
✓ Branch 2 taken 1017 times.
|
57017 | while (!produced_->empty()) |
| 248 | { | ||
| 249 | char value; | ||
| 250 |
1/2✓ Branch 1 taken 28000 times.
✗ Branch 2 not taken.
|
28000 | bool poped = produced_->pop(value); |
| 251 |
1/2✓ Branch 0 taken 28000 times.
✗ Branch 1 not taken.
|
28000 | if (poped) |
| 252 | { | ||
| 253 | 28000 | nb_char_read_++; | |
| 254 |
1/2✓ Branch 1 taken 28000 times.
✗ Branch 2 not taken.
|
28000 | serialized_read_.set(value); |
| 255 | } | ||
| 256 | else | ||
| 257 | { | ||
| 258 | ✗ | break; | |
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | 1017 | bool read = serialized_read_.read(serializable); | |
| 263 | |||
| 264 | 1017 | return read; | |
| 265 | } | ||
| 266 | |||
| 267 | template <class Serializable, int QUEUE_SIZE> | ||
| 268 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::clear() | ||
| 269 | { | ||
| 270 | char foo; | ||
| 271 | while (!produced_->empty()) | ||
| 272 | { | ||
| 273 | produced_->pop(foo); | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 277 | template <class Serializable, int QUEUE_SIZE> | ||
| 278 | 1000 | bool Exchange_manager_memory<Serializable, QUEUE_SIZE>::write_serialized( | |
| 279 | const Serializable &serializable) | ||
| 280 | { | ||
| 281 | 1000 | bool everything_shared = true; | |
| 282 | |||
| 283 | 1000 | serialized_write_.write(serializable, serializable_size_); | |
| 284 | |||
| 285 |
2/2✓ Branch 1 taken 28000 times.
✓ Branch 2 taken 1000 times.
|
57000 | while (!serialized_write_.empty()) |
| 286 | { | ||
| 287 | 28000 | char value = serialized_write_.front(); | |
| 288 |
1/2✓ Branch 1 taken 28000 times.
✗ Branch 2 not taken.
|
28000 | bool pushed = produced_->bounded_push(value); |
| 289 | |||
| 290 |
1/2✓ Branch 0 taken 28000 times.
✗ Branch 1 not taken.
|
28000 | if (pushed) |
| 291 | { | ||
| 292 | 28000 | nb_char_written_++; | |
| 293 | 28000 | serialized_write_.pop(); | |
| 294 | } | ||
| 295 | else | ||
| 296 | { | ||
| 297 | ✗ | everything_shared = false; | |
| 298 | ✗ | break; | |
| 299 | } | ||
| 300 | } | ||
| 301 | |||
| 302 | 1000 | return everything_shared; | |
| 303 | } | ||
| 304 | |||
| 305 | template <class Serializable, int QUEUE_SIZE> | ||
| 306 | 1010 | bool Exchange_manager_memory<Serializable, QUEUE_SIZE>::purge_feedbacks() | |
| 307 | { | ||
| 308 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1010 times.
|
1010 | while (!consumed_buffer_.empty()) |
| 309 | { | ||
| 310 | ✗ | int id = consumed_buffer_.front(); | |
| 311 | ✗ | bool pushed = consumed_->push(id); | |
| 312 | ✗ | if (!pushed) | |
| 313 | { | ||
| 314 | ✗ | return false; | |
| 315 | } | ||
| 316 | else | ||
| 317 | { | ||
| 318 | ✗ | consumed_buffer_.pop_front(); | |
| 319 | } | ||
| 320 | } | ||
| 321 | |||
| 322 | 1010 | return true; | |
| 323 | } | ||
| 324 | |||
| 325 | template <class Serializable, int QUEUE_SIZE> | ||
| 326 | 1000 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::write_serialized_id( | |
| 327 | int id) | ||
| 328 | { | ||
| 329 | // if some consumed id could previously not be set in the shared memory | ||
| 330 | // (because this latest was full), they have been buffered | ||
| 331 | // in consumed_buffer_. Trying to purge it. | ||
| 332 | 1000 | purge_feedbacks(); | |
| 333 | |||
| 334 | // trying to push id that was read into consumed_, | ||
| 335 | // to inform the producer that this item has been consumed | ||
| 336 | 1000 | bool pushed = consumed_->push(id); | |
| 337 | |||
| 338 | // if consumed_ is full, we buffer | ||
| 339 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1000 times.
|
1000 | if (!pushed) |
| 340 | { | ||
| 341 | ✗ | consumed_buffer_.push_back(id); | |
| 342 | } | ||
| 343 | 1000 | } | |
| 344 | |||
| 345 | template <class Serializable, int QUEUE_SIZE> | ||
| 346 | 3044 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::get_consumed_ids( | |
| 347 | std::deque<int> &get_consumed_ids) | ||
| 348 | { | ||
| 349 | int id; | ||
| 350 | bool has_consumed; | ||
| 351 | |||
| 352 |
2/2✓ Branch 0 taken 2022 times.
✓ Branch 1 taken 1022 times.
|
5066 | while (has_consumed) |
| 353 | { | ||
| 354 |
1/2✓ Branch 1 taken 2022 times.
✗ Branch 2 not taken.
|
2022 | has_consumed = consumed_->pop(id); |
| 355 | |||
| 356 |
2/2✓ Branch 0 taken 1000 times.
✓ Branch 1 taken 1022 times.
|
2022 | if (has_consumed) |
| 357 | { | ||
| 358 |
1/2✓ Branch 1 taken 1000 times.
✗ Branch 2 not taken.
|
1000 | get_consumed_ids.push_back(id); |
| 359 | } | ||
| 360 | } | ||
| 361 | 1022 | } | |
| 362 | |||
| 363 | template <class Serializable, int QUEUE_SIZE> | ||
| 364 | 10 | void Exchange_manager_memory<Serializable, QUEUE_SIZE>::reset_char_count() | |
| 365 | { | ||
| 366 | 10 | nb_char_read_ = 0; | |
| 367 | 10 | nb_char_written_ = 0; | |
| 368 | 10 | } | |
| 369 | |||
| 370 | template <class Serializable, int QUEUE_SIZE> | ||
| 371 | 1022 | int Exchange_manager_memory<Serializable, QUEUE_SIZE>::nb_char_written() | |
| 372 | { | ||
| 373 | 1022 | return nb_char_written_; | |
| 374 | } | ||
| 375 | |||
| 376 | template <class Serializable, int QUEUE_SIZE> | ||
| 377 | int Exchange_manager_memory<Serializable, QUEUE_SIZE>::nb_char_read() | ||
| 378 | { | ||
| 379 | return nb_char_read_; | ||
| 380 | } | ||
| 381 | |||
| 382 | template <class Serializable, int QUEUE_SIZE> | ||
| 383 | bool Exchange_manager_memory<Serializable, QUEUE_SIZE>::consumer_queue_empty() | ||
| 384 | const | ||
| 385 | { | ||
| 386 | return consumed_->empty(); | ||
| 387 | } | ||
| 388 | |||
| 389 | template <class Serializable, int QUEUE_SIZE> | ||
| 390 | bool Exchange_manager_memory<Serializable, QUEUE_SIZE>::producer_queue_empty() | ||
| 391 | const | ||
| 392 | { | ||
| 393 | return produced_->empty(); | ||
| 394 | } | ||
| 395 |