Instrument Neutral Distributed Interface INDI 2.2.5
SharedBuffer.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 Copyright(c) 2022 Ludovic Pollet. All rights reserved.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
17*******************************************************************************/
18
19extern "C" {
20 // Load shm_open_anon but force it to have static symbol only
21 static int shm_open_anon(void);
22 #include "../libs/indicore/shm_open_anon.c"
23}
24
25#include <system_error>
26
27#include "SharedBuffer.h"
28
29
30#ifdef __linux__
31#ifndef _GNU_SOURCE
32#define _GNU_SOURCE
33#endif
34#include <linux/unistd.h>
35#endif
36
37#include <errno.h>
38#include <unistd.h>
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <sys/mman.h>
42#include <fcntl.h>
43
44#include <string.h>
45
46#include <sys/mman.h>
47
48
50{
51 fd = -1;
52 size = 0;
53}
54
59
61{
62 release();
63 this->fd = fd;
64 if (fd == -1)
65 {
66 size = 0;
67 return;
68 }
69
70 struct stat sb;
71
72 if (fstat(fd, &sb) == -1)
73 {
74 int e = errno;
75 throw std::system_error(e, std::generic_category(), "Unable to stat buffer");
76 }
77
78 size = sb.st_size;
79}
80
82{
83 if (fd != -1)
84 {
85 close(fd);
86 fd = -1;
87 }
88 size = 0;
89}
90
92{
93 if (fd == -1)
94 {
95 throw std::runtime_error("SharedBuffer is not allocated");
96 }
97 return fd;
98}
99
100
101void SharedBuffer::write(const void * data, ssize_t offset, ssize_t writeSize)
102{
103 if (writeSize == 0)
104 {
105 return;
106 }
107
108 if (size < offset + writeSize)
109 {
110 throw std::runtime_error("Attempt to write beyond past");
111 }
112
113 void * mmapped = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
114 if (mmapped == MAP_FAILED)
115 {
116 perror("mmap");
117 throw std::runtime_error("Mmap failed");
118 }
119
120 memcpy((void*)((char*)mmapped + offset), data, writeSize);
121
122 if (munmap(mmapped, size) == -1)
123 {
124 perror("munmap");
125 throw std::runtime_error("Munmap failed");
126 }
127
128}
129
130void SharedBuffer::allocate(ssize_t nsize)
131{
132 release();
133 fd = shm_open_anon();
134 if (fd == -1)
135 {
136 throw std::system_error(errno, std::generic_category(), "memfd_create");
137 }
138
139 int ret = ftruncate(fd, nsize);
140 if (ret == -1)
141 {
142 throw std::system_error(errno, std::generic_category(), "memfd_create");
143 }
144
145 size = nsize;
146}
147
int getFd() const
void attach(int fd)
void allocate(ssize_t size)
void write(const void *buffer, ssize_t offset, ssize_t size)
int errno
int fd
int shm_open_anon(void)