9#include "daq/rfarm/manager/SharedMem.h"
25SharedMem::SharedMem(
const char* name,
int size)
28 std::string tmpPathName;
30 if (strcmp(name,
"private") != 0) {
33 tmpPathName = getTmpFileName(getenv(
"USER"), name);
34 tmpFilefd = open(tmpPathName.c_str(), O_CREAT | O_EXCL | O_RDWR, 0644);
38 printf(
"SharedMem: Creating a new tmp file %s\n", name);
41 }
else if (tmpFilefd == -1 && errno == EEXIST) {
42 printf(
"SharedMem: Found existing tmp file %s\n", name);
45 printf(
"SharedMem: error to open tmp file %s\n", tmpPathName.c_str());
48 m_shmkey = ftok(tmpPathName.c_str(), 1);
49 m_semkey = ftok(tmpPathName.c_str(), 2);
55 printf(
"SharedMem: Opening private shared memory\n");
67 perror(
"SharedMem::shmget");
70 m_shmadr = (
int*) shmat(
m_shmid, 0, 0);
71 if (m_shmadr == (
int*) - 1) {
72 perror(
"SharedMem::shmat");
87 if (semctl(
m_semid, 0, SETVAL, semval) == -1) {
88 perror(
"Initializing semaphore with semctl() failed.");
91 }
else if (errno == EEXIST) {
93 printf(
"Found existing Semaphore ID %d for key $%X\n",
m_semid,
m_semkey);
96 perror(
"SharedMem::shmget");
103 bool updateneeded =
m_new;
106 int shmid = 0, semid = 0;
107 if (getIdFromTmpFileName(tmpPathName.c_str(), shmid, semid)) {
109 printf(
"tmp file %s content still uptodate\n", tmpPathName.c_str());
117 int tmpFilefd = open(tmpPathName.c_str(), O_RDWR, 0644);
119 printf(
"SharedMem: error to reopen tmp file %s\n", tmpPathName.c_str());
123 int is = write(tmpFilefd, shminfo, strlen(shminfo));
124 if (is < 0) perror(
"write");
126 printf(
"tmp file %s has been updated with shminfo \"%s\"\n", tmpPathName.c_str(), shminfo);
129 printf(
"SharedMem: created. shmid = %d, semid = %d\n",
m_shmid,
m_semid);
133SharedMem::SharedMem(
int shm_id,
int sem_id,
int size)
136 m_shmadr = (
int*) shmat(
m_shmid, 0, SHM_RDONLY);
137 if (m_shmadr == (
int*) - 1) {
138 perror(
"SharedMem::shmat");
142 printf(
"SharedMem: open shmid = %d, semid = %d\n",
m_shmid,
m_semid);
157void* SharedMem::ptr(
void)
159 return (
void*) m_shmadr;
162int SharedMem::shmid(
void)
167bool SharedMem::IsCreated(
void)
172std::string SharedMem::getTmpFileName(std::string user, std::string name)
174 return string(
"/tmp/") + user + string(
"_SHM_") + name;
177bool SharedMem::getIdFromTmpFileName(std::string filename,
int& shmid,
int& semid)
180 int fd = open(filename.c_str(), O_RDONLY);
182 printf(
"SharedMem: error to reopen tmp file %s\n", filename.c_str());
187 memset(shminfo, 0,
sizeof(shminfo));
188 int n = read(fd, shminfo,
sizeof(shminfo));
190 sscanf(shminfo,
"%d %d", &shmid, &semid);
191 return (n >= 3 && shmid >= 0 && semid >= 0);
194void SharedMem::lock()
200 while (semop(
m_semid, &sb, 1) == -1) {
201 if (errno == EINTR) {
205 perror(
"lock:semop");
211void SharedMem::unlock()
217 while (semop(
m_semid, &sb, 1) == -1) {
218 if (errno == EINTR) {
222 perror(
"unlock:semop");
228bool SharedMem::isLocked()
231 return (semctl(
m_semid, 0, GETVAL, ignored) == 0);
key_t m_shmkey
SHM key, see shmget(2).
int m_shmid
shared memory id
bool m_new
True if we created the ring buffer ourselves (and need to clean it).
key_t m_semkey
Semaphore key.
Abstract base class for different kinds of events.