6 #include <spdlog/spdlog.h>
17 struct ::stat file_stats;
19 if (::ftruncate(file_descriptor, bytes) < 0) {
20 throw std::runtime_error(
"Error truncating file, errno is " +
21 std::to_string(errno));
24 ::fstat(file_descriptor, &file_stats);
25 if (file_stats.st_size < bytes) {
26 throw std::runtime_error(
27 "Error allocating " + std::to_string(bytes) +
28 " bytes in shared memory. Errno is : " + std::to_string(errno));
33 : name_(name), size_(size) {
36 mode_t existing_umask = ::umask(0);
38 ::shm_open(name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0666);
39 ::umask(existing_umask);
40 if (file_descriptor < 0) {
41 if (errno == EINVAL) {
42 spdlog::error(
"Cannot open shared memory \"{}\": file name is invalid.",
44 }
else if (errno == EEXIST) {
46 "Cannot open shared memory \"{}\": file already exists. Is a spine "
50 "If not other spine is running but a previous spine did not exit "
51 "properly, you can run ``sudo rm /dev/shm{}`` to clean this error.",
54 spdlog::error(
"Cannot open shared memory file: errno is {}", errno);
56 throw std::runtime_error(
"Error opening file");
61 mmap_ = ::mmap(
nullptr,
size, PROT_READ | PROT_WRITE, MAP_SHARED,
63 if (mmap_ == MAP_FAILED) {
64 throw std::runtime_error(
"Error mapping file");
66 if (::close(file_descriptor) < 0) {
67 throw std::runtime_error(
"Error closing file descriptor");
71 mmap_request_ =
static_cast<uint32_t*
>(mmap_);
72 mmap_size_ =
static_cast<uint32_t*
>(mmap_request_ + 1);
73 mmap_data_ =
reinterpret_cast<char*
>(mmap_size_ + 1);
77 if (::munmap(mmap_, size_) < 0) {
78 spdlog::error(
"Failed to unmap memory; errno is {}", errno);
80 if (::shm_unlink(name_.c_str()) < 0) {
81 spdlog::error(
"Failed to unlink shared memory; errno is {}", errno);
86 *mmap_request_ =
static_cast<uint32_t
>(
request);
90 if (size_ <=
size + 2 *
sizeof(uint32_t)) {
92 "Trying to write {} bytes to agent interface buffer of size {} bytes",
94 throw std::runtime_error(
"Agent interface buffer overflow");
void set_request(Request request)
Set current request in shared memory.
void write(char *data, size_t size)
Write data to the data buffer in shared memory.
uint32_t size() const
Get size of current data buffer.
~AgentInterface()
Unmap memory and unlink shared memory object.
AgentInterface(const std::string &name, size_t size)
Open interface to the agent at a given shared-memory file.
const char * data() const
Get pointer to data buffer.
Request request() const
Get current request from shared memory.
Flag set by the agent to request an operation from the spine.
Inter-process communication protocol with the spine.
void allocate_file(int file_descriptor, int bytes)
Allocate file with some error handling.