Belle II Software  release-08-01-10
SharedMemory.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include "daq/slc/system/SharedMemory.h"
9 
10 #include <sys/stat.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <fcntl.h>
14 #include <sys/mman.h>
15 #include <errno.h>
16 
17 using namespace Belle2;
18 
19 bool SharedMemory::unlink(const std::string& path)
20 {
21  return (::shm_unlink(path.c_str()) == -1);
22 }
23 
24 SharedMemory::SharedMemory()
25  : m_fd(-1), m_path(), m_size(0), m_addr(NULL) {}
26 
27 SharedMemory::SharedMemory(const std::string& path, size_t size)
28  : m_fd(-1), m_path(path), m_size(size), m_addr(NULL)
29 {
30 }
31 
32 SharedMemory::SharedMemory(const SharedMemory& file)
33  : m_fd(file.m_fd), m_path(file.m_path),
34  m_size(file.m_size), m_addr(file.m_addr) {}
35 
36 SharedMemory::~SharedMemory() {}
37 
38 bool SharedMemory::open(const std::string& path, size_t size)
39 {
40  errno = 0;
41  int fd = ::shm_open(path.c_str(), O_CREAT | O_EXCL | O_RDWR, 0666);
42  if (fd < 0) {
43  if (errno != EEXIST) {
44  perror("shm_oepn");
45  return false;
46  }
47  fd = ::shm_open(path.c_str(), O_CREAT | O_RDWR, 0666);
48  if (fd < 0) {
49  perror("shm_oepn");
50  return false;
51  }
52  }
53  m_fd = fd;
54  m_path = path;
55  truncate(size);
56  return true;
57 }
58 
59 bool SharedMemory::open()
60 {
61  return open(m_path, m_size);
62 }
63 
64 void SharedMemory::close()
65 {
66  if (m_fd > 0) {
67  if (m_addr != NULL) munmap(m_addr, m_size);
68  ::close(m_fd);
69  m_fd = 0;
70  }
71 }
72 
73 bool SharedMemory::truncate(size_t size)
74 {
75  if (size > 0) {
76  ::ftruncate(m_fd, size);
77  m_size = size;
78  return true;
79  } else {
80  struct stat st;
81  fstat(m_fd, &st);
82  m_size = st.st_size;
83  }
84  return false;
85 }
86 
87 
88 void* SharedMemory::map(size_t offset, size_t size)
89 {
90  errno = 0;
91  void* addr = ::mmap(NULL, size, PROT_READ | PROT_WRITE,
92  MAP_SHARED, m_fd, offset);
93  if (addr == MAP_FAILED) {
94  perror("mmap");
95  addr = NULL;
96  }
97  m_addr = addr;
98  m_size = size;
99  return addr;
100 }
101 
102 void* SharedMemory::map()
103 {
104  if (m_addr == NULL) m_addr = map(0, m_size);
105  return m_addr;
106 }
107 
108 bool SharedMemory::unlink()
109 {
110  close();
111  return (unlink(m_path));
112 }
113 
114 bool SharedMemory::seekTo(size_t offset)
115 {
116  return (lseek(m_fd, offset, SEEK_SET) == -1);
117 }
118 
119 bool SharedMemory::seekBy(size_t offset)
120 {
121  return (lseek(m_fd, offset, SEEK_CUR) == -1);
122 }
123 
124 bool SharedMemory::isOpened()
125 {
126  return (m_fd != 0);
127 }
128 
129 const SharedMemory& SharedMemory::operator=(const SharedMemory& file)
130 {
131  m_fd = file.m_fd;
132  m_path = file.m_path;
133  m_size = file.m_size;
134  m_addr = file.m_addr;
135  return *this;
136 }
137 
Abstract base class for different kinds of events.