SHM
共有メモリを用いた高速で扱いやすいプロセス間通信マネージャ
shared_memory.cpp
1 #include <shm_base.hpp>
2 
3 namespace irlab
4 {
5 
6 namespace shm
7 {
8 
20 int
21 disconnectMemory(std::string name)
22 {
23  if (name[0] == '/')
24  {
25  name = name.erase(0, 1);
26  }
27  std::string str_buf = "/shm_" + regex_replace(name, std::regex("/"), "_");
28  return shm_unlink(str_buf.c_str());
29 }
30 
31 
32 SharedMemory::SharedMemory(int oflag, PERM perm)
33 : shm_fd(-1)
34 , shm_oflag(oflag)
35 , shm_perm(perm)
36 , shm_size(0)
37 , shm_ptr(nullptr)
38 {
39 }
40 
41 
42 size_t
43 SharedMemory::getSize() const
44 {
45  return shm_size;
46 }
47 
48 
49 unsigned char*
50 SharedMemory::getPtr()
51 {
52  return shm_ptr;
53 }
54 
55 SharedMemoryPosix::SharedMemoryPosix(std::string name, int oflag, PERM perm)
56 : SharedMemory(oflag, perm)
57 , shm_name(name)
58 {
59  if (shm_name[0] == '/')
60  {
61  shm_name = shm_name.erase(0, 1);
62  }
63 }
64 
65 
66 SharedMemoryPosix::~SharedMemoryPosix()
67 {
68  if (shm_fd >= 0)
69  {
70  close(shm_fd);
71  }
72 }
73 
74 
75 bool
76 SharedMemoryPosix::connect(size_t size)
77 {
78  std::string str_buf = "/shm_" + regex_replace(shm_name, std::regex("/"), "_");
79 
80  shm_fd = shm_open(str_buf.c_str(), shm_oflag, static_cast<mode_t>(shm_perm));
81  if (shm_fd < 0)
82  {
83  return false;
84  }
85  struct stat stat;
86  fstat(shm_fd, &stat);
87  if (size == 0)
88  {
89  shm_size = stat.st_size;
90  } else {
91  shm_size = size;
92  if (stat.st_size < shm_size)
93  {
94  if (ftruncate(shm_fd, shm_size) < 0)
95  {
96  throw std::runtime_error("shm::getMemory(): Could not change shared memory size!");
97  }
98  // To Update stat.st_size
99  fstat(shm_fd, &stat);
100  }
101  }
102  shm_ptr = reinterpret_cast<unsigned char *>(mmap(NULL,
103  stat.st_size,
104  PROT_READ|PROT_WRITE,
105  MAP_SHARED,
106  shm_fd,
107  0));
108 
109  if (shm_ptr == MAP_FAILED) {
110  close(shm_fd);
111  shm_fd = -1;
112  return false;
113  }
114 
115  return true;
116 }
117 
118 
119 int
120 SharedMemoryPosix::disconnect()
121 {
122  return disconnectMemory(shm_name);
123 }
124 
125 
126 bool
127 SharedMemoryPosix::isDisconnected() const
128 {
129  struct stat stat;
130  if (shm_fd < 0)
131  {
132  return true;
133  }
134 
135  fstat(shm_fd, &stat);
136  if (stat.st_nlink <= 0)
137  {
138  return true;
139  }
140  return false;
141 }
142 
143 
144 }
145 
146 }
147 
共有メモリへのアクセス方法やリングバッファなどの基本的なクラスの定義
int disconnectMemory(std::string name)
共有メモリを破棄する(POSIX版)