-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShm.h
More file actions
90 lines (83 loc) · 2.51 KB
/
Shm.h
File metadata and controls
90 lines (83 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <cstring>
#include <pthread.h>
#include <cstdint>
class Shm {
public:
Shm(const char* name="shm", size_t size=0, bool create=true);
void write(std::string msg);
const std::string read();
bool fail();
bool lock();
bool unlock();
~Shm();
private:
size_t size;
const char* name;
int fd;
pthread_mutex_t* mutex; //lock address
u_int8_t* buffer; // memory address
};
Shm::Shm(const char* name, size_t size, bool create) {
this->name = name;
this->size = size;
if (create) {
this->fd = shm_open(this->name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
if (this->fd == -1) {
throw std::runtime_error("Cannot setup shared memory");
}
}
else {
this->fd = shm_open(this->name, O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
if (this->fd == -1) {
throw std::runtime_error("Cannot access shared memory");
}
}
if (ftruncate(this->fd, this->size) == -1) {
throw std::runtime_error("cannot resize shared memory");
}
auto ptr=mmap(0, this->size, PROT_WRITE | PROT_READ, MAP_SHARED, this->fd, 0);
this->mutex=(pthread_mutex_t*)ptr;
this->buffer = (uint8_t*)ptr + sizeof(pthread_mutex_t);
if (this->mutex == MAP_FAILED){
throw std::runtime_error("Cannot setup mutex lock");
}
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(mutex, &attr);
printf("Created Shared memory %s with size %ld\n",name,size);
}
void Shm::write(std::string msg){
pthread_mutex_lock(mutex);
strncpy((char *)this->buffer, msg.data(), this->size);
pthread_mutex_unlock(mutex);
}
const std::string Shm::read() {
std::string msg;
pthread_mutex_lock(mutex);
msg=(char*)buffer;
pthread_mutex_unlock(mutex);
return msg;
}
Shm::~Shm() {
int res = pthread_mutex_trylock(mutex);
if (res == 0) {
pthread_mutex_unlock(mutex);
} else if (res == EBUSY) {
std::cerr << "Mutex still in use, skipping destroy\n";
} else {
perror("Trylock failed");
}
if (this->mutex && this->mutex != MAP_FAILED) {
pthread_mutex_destroy(this->mutex);
munmap(this->mutex, this->size);
}
close(this->fd);
shm_unlink(this->name);
}