| 6964 | */ |
| 6965 | template <typename type_> |
| 6966 | class mmap_array { |
| 6967 | type_ *data_ = nullptr; |
| 6968 | std::size_t size_ = 0; |
| 6969 | |
| 6970 | public: |
| 6971 | mmap_array(std::size_t count) : size_(count) { |
| 6972 | // The basic mmap call, creating an anonymous region: |
| 6973 | void *addr = ::mmap( // |
| 6974 | nullptr, // no specific address |
| 6975 | size_ * sizeof(type_), // length in bytes |
| 6976 | PROT_READ | PROT_WRITE, // read/write allowed |
| 6977 | MAP_SHARED | MAP_ANONYMOUS, // not backed by a file |
| 6978 | -1, // no file descriptor |
| 6979 | 0 // offset |
| 6980 | ); |
| 6981 | if (addr == MAP_FAILED) throw std::bad_alloc(); |
| 6982 | |
| 6983 | // Ensure the pages are locked in memory: |
| 6984 | if (mlock(addr, size_ * sizeof(type_)) != 0) { |
| 6985 | ::munmap(addr, size_ * sizeof(type_)); |
| 6986 | throw std::runtime_error("`mlock` failed"); |
| 6987 | } |
| 6988 | |
| 6989 | data_ = static_cast<type_ *>(addr); |
| 6990 | } |
| 6991 | |
| 6992 | ~mmap_array() noexcept { |
| 6993 | ::munlock(data_, size_ * sizeof(type_)); |
| 6994 | ::munmap(data_, size_ * sizeof(type_)); |
| 6995 | } |
| 6996 | |
| 6997 | type_ *begin() const noexcept { return data_; } |
| 6998 | type_ *end() const noexcept { return data_ + size_; } |
| 6999 | type_ &operator[](std::size_t idx) noexcept { return data_[idx]; } |
| 7000 | type_ operator[](std::size_t idx) const noexcept { return data_[idx]; } |
| 7001 | std::size_t size() const noexcept { return size_; } |
| 7002 | }; |
| 7003 | |
| 7004 | /** |
| 7005 | * @brief Wraps the `rpc_buffer_t` with metadata about the client address. |
nothing calls this directly
no outgoing calls
no test coverage detected