9 #include "daq/dqm/DqmSharedMem.h"
15 #include <sys/types.h>
25 DqmSharedMem::DqmSharedMem(
const char* name,
int size)
27 std::string tmpPathName;
29 if (strcmp(name,
"private") != 0) {
30 tmpPathName = getTmpFileName(getenv(
"USER"), name);
31 m_pathfd = open(tmpPathName.c_str(), O_CREAT | O_EXCL | O_RDWR, 0644);
33 printf(
"DqmSharedMem: Creating a shared memory with key %s\n", name);
35 }
else if (m_pathfd == -1 && errno == EEXIST) {
36 printf(
"DqmSharedMem: Attaching the ring buffer with key %s\n", name);
39 printf(
"DqmSharedMem: error to open shm file\n");
42 m_shmkey = ftok(tmpPathName.c_str(), 1);
43 m_semkey = ftok(tmpPathName.c_str(), 2);
46 m_shmkey = IPC_PRIVATE;
47 m_semkey = IPC_PRIVATE;
48 printf(
"DqmSharedMem: Opening private shared memory\n");
51 printf(
"Shared memory/Semaphore Keys: $%X $%X\n", m_shmkey, m_semkey);
58 m_shmid = shmget(m_shmkey, size * 4, IPC_CREAT | 0644);
60 perror(
"DqmSharedMem::shmget");
63 m_shmadr = (
int*) shmat(m_shmid, 0, 0);
64 if (m_shmadr == (
int*) - 1) {
65 perror(
"DqmSharedMem::shmat");
75 m_semid = semget(m_semkey, 1, IPC_CREAT | 0644);
79 if (semctl(m_semid, 0, SETVAL, semval) == -1) {
80 printf(
"Initializing semaphore with semctl() failed.\n");
82 }
else if (errno == EEXIST) {
83 m_semid = semget(m_semkey, 1, 0600);
86 perror(
"DqmSharedMem::shmget");
104 sprintf(shminfo,
"%d %d\n", m_shmid, m_semid);
105 int is = write(m_pathfd, shminfo, strlen(shminfo));
106 if (is < 0) perror(
"write");
109 printf(
"DqmSharedMem: created. shmid = %d, semid = %d\n", m_shmid, m_semid);
113 DqmSharedMem::DqmSharedMem(
int shm_id,
int sem_id,
int size)
116 m_shmadr = (
int*) shmat(m_shmid, 0, SHM_RDONLY);
117 if (m_shmadr == (
int*) - 1) {
118 perror(
"DqmSharedMem::shmat");
122 printf(
"DqmSharedMem: open shmid = %d, semid = %d\n", m_shmid, m_semid);
137 void* DqmSharedMem::ptr(
void)
139 return (
void*) m_shmadr;
142 int DqmSharedMem::shmid(
void)
147 bool DqmSharedMem::IsCreated(
void)
152 std::string DqmSharedMem::getTmpFileName(std::string user, std::string name)
154 return string(
"/tmp/") + user + string(
"_SHM_") + name;
157 bool DqmSharedMem::getIdFromTmpFileName(std::string filename,
int& shmid,
int& semid)
160 int fd = open(filename.c_str(), O_RDONLY);
162 printf(
"DqmSharedMem: error to reopen tmp file %s\n", filename.c_str());
167 memset(shminfo, 0,
sizeof(shminfo));
168 int n = read(fd, shminfo,
sizeof(shminfo));
170 sscanf(shminfo,
"%d %d", &shmid, &semid);
171 return (n >= 3 && shmid >= 0 && semid >= 0);
174 void DqmSharedMem::lock()
180 while (semop(m_semid, &sb, 1) == -1) {
181 if (errno == EINTR) {
185 perror(
"lock:semop");
191 void DqmSharedMem::unlock()
197 while (semop(m_semid, &sb, 1) == -1) {
198 if (errno == EINTR) {
202 perror(
"unlock:semop");
208 bool DqmSharedMem::isLocked()
211 return (semctl(m_semid, 0, GETVAL, ignored) == 0);
Abstract base class for different kinds of events.