9 #include "daq/rfarm/manager/SharedMem.h"
15 #include <sys/types.h>
25 SharedMem::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);
53 m_shmkey = IPC_PRIVATE;
54 m_semkey = IPC_PRIVATE;
55 printf(
"SharedMem: Opening private shared memory\n");
58 printf(
"Shared memory/Semaphore Keys: $%X $%X\n", m_shmkey, m_semkey);
65 m_shmid = shmget(m_shmkey, size * 4, IPC_CREAT | 0644);
67 perror(
"SharedMem::shmget");
70 m_shmadr = (
int*) shmat(m_shmid, 0, 0);
71 if (m_shmadr == (
int*) - 1) {
72 perror(
"SharedMem::shmat");
82 m_semid = semget(m_semkey, 1, IPC_CREAT | IPC_EXCL | 0666);
86 printf(
"Semaphore ID %d created for key $%X\n", m_semid, m_semkey);
87 if (semctl(m_semid, 0, SETVAL, semval) == -1) {
88 perror(
"Initializing semaphore with semctl() failed.");
91 }
else if (errno == EEXIST) {
92 m_semid = semget(m_semkey, 1, 0);
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)) {
108 updateneeded = (shmid != m_shmid || semid != m_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());
122 snprintf(shminfo,
sizeof(shminfo),
"%d %d\n", m_shmid, m_semid);
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);
133 SharedMem::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);
157 void* SharedMem::ptr(
void)
159 return (
void*) m_shmadr;
162 int SharedMem::shmid(
void)
167 bool SharedMem::IsCreated(
void)
172 std::string SharedMem::getTmpFileName(std::string user, std::string name)
174 return string(
"/tmp/") + user + string(
"_SHM_") + name;
177 bool 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);
194 void SharedMem::lock()
200 while (semop(m_semid, &sb, 1) == -1) {
201 if (errno == EINTR) {
205 perror(
"lock:semop");
211 void SharedMem::unlock()
217 while (semop(m_semid, &sb, 1) == -1) {
218 if (errno == EINTR) {
222 perror(
"unlock:semop");
228 bool SharedMem::isLocked()
231 return (semctl(m_semid, 0, GETVAL, ignored) == 0);
Abstract base class for different kinds of events.