9#include "daq/dqm/DqmSharedMem.h"
25DqmSharedMem::DqmSharedMem(
const char* name,
int size,
bool writeable,
const char* user)
28 std::string tmpPathName;
30 if (strcmp(name,
"private") != 0) {
33 tmpPathName = getTmpFileName(user, name);
35 tmpPathName = getTmpFileName(getenv(
"USER"), name);
37 printf(
"Open Shared Memory: %s writeable %d\n", tmpPathName.c_str(), writeable);
38 int tmpFilefd = open(tmpPathName.c_str(), O_CREAT | O_EXCL | O_RDWR, 0644);
42 printf(
"DqmSharedMem: Creating a new tmp file %s\n", name);
45 }
else if (tmpFilefd == -1 && errno == EEXIST) {
46 printf(
"DqmSharedMem: Updating existing tmp file %s\n", name);
49 printf(
"DqmSharedMem: error to open tmp file %s\n", tmpPathName.c_str());
52 m_shmkey = ftok(tmpPathName.c_str(), 1);
53 m_semkey = ftok(tmpPathName.c_str(), 2);
59 printf(
"DqmSharedMem: Opening private shared memory\n");
72 }
else if (errno == EEXIST) {
77 perror(
"SharedMem::shmget");
81 printf(
"ShM ID %d opened Readonly\n",
m_shmid);
82 m_shmadr = (
int*) shmat(
m_shmid, 0, SHM_RDONLY);
84 printf(
"ShM ID %d opened Writeable\n",
m_shmid);
85 m_shmadr = (
int*) shmat(
m_shmid, 0, 0);
87 if (m_shmadr == (
int*) - 1) {
88 perror(
"DqmSharedMem::shmat");
103 if (semctl(
m_semid, 0, SETVAL, semval) == -1) {
104 perror(
"Initializing semaphore with semctl() failed.");
107 }
else if (errno == EEXIST) {
109 printf(
"Found existing Semaphore ID %d for key $%X\n",
m_semid,
m_semkey);
112 perror(
"DqmSharedMem::shmget");
119 bool updateneeded =
m_new;
122 int shmid = 0, semid = 0;
123 if (getIdFromTmpFileName(tmpPathName.c_str(), shmid, semid)) {
125 printf(
"tmp file %s content still uptodate\n", tmpPathName.c_str());
133 int tmpFilefd = open(tmpPathName.c_str(), O_RDWR, 0644);
135 printf(
"SharedMem: error to reopen tmp file %s\n", tmpPathName.c_str());
139 int is = write(tmpFilefd, shminfo, strlen(shminfo));
140 if (is < 0) perror(
"write");
142 printf(
"tmp file %s has been updated with shminfo \"%s\"\n", tmpPathName.c_str(), shminfo);
145 printf(
"DqmSharedMem: opened. shmid = %d, semid = %d\n",
m_shmid,
m_semid);
148DqmSharedMem::DqmSharedMem(
int shm_id,
int sem_id)
152 m_shmadr = (
int*) shmat(
m_shmid, 0, SHM_RDONLY);
153 if (m_shmadr == (
int*) - 1) {
154 perror(
"DqmSharedMem::shmat");
158 printf(
"DqmSharedMem: open shmid = %d, semid = %d\n",
m_shmid,
m_semid);
173void* DqmSharedMem::ptr(
void)
175 return (
void*) m_shmadr;
178int DqmSharedMem::shmid(
void)
183bool DqmSharedMem::IsCreated(
void)
188std::string DqmSharedMem::getTmpFileName(std::string user, std::string name)
190 return string(
"/tmp/") + user + string(
"_SHM_") + name;
193bool DqmSharedMem::getIdFromTmpFileName(std::string filename,
int& shmid,
int& semid)
196 int fd = open(filename.c_str(), O_RDONLY);
198 printf(
"DqmSharedMem: error to reopen tmp file %s\n", filename.c_str());
203 memset(shminfo, 0,
sizeof(shminfo));
204 int n = read(fd, shminfo,
sizeof(shminfo));
206 sscanf(shminfo,
"%d %d", &shmid, &semid);
207 return (n >= 3 && shmid >= 0 && semid >= 0);
210void DqmSharedMem::lock()
216 while (semop(
m_semid, &sb, 1) == -1) {
217 if (errno == EINTR) {
221 perror(
"lock:semop");
227void DqmSharedMem::unlock()
233 while (semop(
m_semid, &sb, 1) == -1) {
234 if (errno == EINTR) {
238 perror(
"unlock:semop");
244bool DqmSharedMem::isLocked()
247 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.