in progress with integratign new shm in multi

This commit is contained in:
maliakal_d 2018-06-12 12:14:55 +02:00
parent bab7d8e3fb
commit b294b3e8b1
7 changed files with 1471 additions and 945 deletions

View File

@ -9,15 +9,15 @@ CFLAGS= -g -DC_ONLY -fPIC
DFLAGS= -g -DDACS_INT DFLAGS= -g -DDACS_INT
INCLUDES?= -IcommonFiles -IslsDetector -I../slsReceiverSoftware/MySocketTCP -IusersFunctions -ImultiSlsDetector -IslsDetectorUtils -IslsDetectorCommand -IslsDetectorAnalysis -IslsReceiverInterface -I../slsReceiverSoftware/include -IthreadFiles -I$(ASM) INCLUDES?= -IcommonFiles -IslsDetector -I../slsReceiverSoftware/MySocketTCP -IusersFunctions -ImultiSlsDetector -IslsDetectorUtils -IslsDetectorCommand -IslsDetectorAnalysis -IslsReceiverInterface -I../slsReceiverSoftware/include -IthreadFiles -IsharedMemory-I$(ASM)
#EPICSFLAGS=-D EPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -Wl,-R/usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -lca -lCom #EPICSFLAGS=-D EPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -Wl,-R/usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -lca -lCom
LIBZMQDIR = ../slsReceiverSoftware/include LIBZMQDIR = ../slsReceiverSoftware/include
LIBZMQ = -L$(LIBZMQDIR) -Wl,-rpath=$(LIBZMQDIR) -lzmq LIBZMQ = -L$(LIBZMQDIR) -Wl,-rpath=$(LIBZMQDIR) -lzmq
SRC_CLNT=slsDetectorAnalysis/fileIO.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/angularConversionStatic.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp slsDetectorAnalysis/postProcessingFuncs.cpp slsReceiverInterface/receiverInterface.cpp slsDetector/slsDetectorUsers.cpp threadFiles/CondVar.cpp threadFiles/Mutex.cpp threadFiles/ThreadPool.cpp #../slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp SRC_CLNT=slsDetectorAnalysis/fileIO.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/angularConversionStatic.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp slsDetectorAnalysis/postProcessingFuncs.cpp slsReceiverInterface/receiverInterface.cpp slsDetector/slsDetectorUsers.cpp threadFiles/CondVar.cpp threadFiles/Mutex.cpp threadFiles/ThreadPool.cpp sharedMemory/SharedMemory.cpp #../slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp
DEPSINCLUDES = $(LIBZMQDIR)/sls_receiver_defs.h $(LIBZMQDIR)/sls_receiver_funcs.h $(LIBZMQDIR)/ansi.h commonFiles/sls_detector_defs.h commonFiles/sls_detector_funcs.h commonFiles/error_defs.h slsDetector/slsDetectorBase.h slsDetectorAnalysis/angCalLogClass.h slsDetectorAnalysis/angleConversionConstant.h slsDetectorAnalysis/badChannelCorrections.h slsDetectorAnalysis/detectorData.h slsDetectorAnalysis/enCalLogClass.h slsDetectorAnalysis/fileIOStatic.h slsDetectorAnalysis/movingStat.h slsDetectorAnalysis/runningStat.h slsDetectorAnalysis/single_photon_hit.h threadFiles/Global.h threadFiles/Task.h usersFunctions/angleFunction.h DEPSINCLUDES = $(LIBZMQDIR)/sls_receiver_defs.h $(LIBZMQDIR)/sls_receiver_funcs.h $(LIBZMQDIR)/ansi.h commonFiles/sls_detector_defs.h commonFiles/sls_detector_funcs.h commonFiles/error_defs.h slsDetector/slsDetectorBase.h slsDetectorAnalysis/angCalLogClass.h slsDetectorAnalysis/angleConversionConstant.h slsDetectorAnalysis/badChannelCorrections.h slsDetectorAnalysis/detectorData.h slsDetectorAnalysis/enCalLogClass.h slsDetectorAnalysis/fileIOStatic.h slsDetectorAnalysis/movingStat.h slsDetectorAnalysis/runningStat.h slsDetectorAnalysis/single_photon_hit.h threadFiles/Global.h threadFiles/Task.h usersFunctions/angleFunction.h sharedMemory/sharedMemory.h commonFiles/sls_detector_exceptions.h

View File

@ -0,0 +1,19 @@
#pragma once
/************************************************
* @file sls_detector_exceptions.h
* @short exceptions defined
***********************************************/
/**
*@short exceptions defined
*/
#include <iostream>
#include <exception>
using namespace std;
struct SharedMemoryException : public exception {
public:
SharedMemoryException() {}
string GetMessage() const { return "Shared Memory Failed";};
};//shmException;

View File

@ -9,84 +9,331 @@ ID: $Id$
********************************************************************/ ********************************************************************/
#include "multiSlsDetector.h" #include "multiSlsDetector.h"
#include "SharedMemory.h"
#include "slsDetector.h"
#include "sls_detector_exceptions.h"
#include "ThreadPool.h" #include "ThreadPool.h"
#include "ZmqSocket.h" #include "ZmqSocket.h"
#include "multiSlsDetectorClient.h" #include "multiSlsDetectorClient.h"
#include "multiSlsDetectorCommand.h" #include "multiSlsDetectorCommand.h"
#include "postProcessingFuncs.h" #include "postProcessingFuncs.h"
#include "slsDetector.h"
#include "usersFunctions.h" #include "usersFunctions.h"
#include <sys/types.h>
#include <iostream> #include <iostream>
#include <string.h>
#include <sstream>
#include <rapidjson/document.h> //json header in zmq stream #include <rapidjson/document.h> //json header in zmq stream
#include <string>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/shm.h> #include <sys/shm.h>
#include <sys/types.h>
#include <vector>
// char ans[MAX_STR_LENGTH];
int multiSlsDetector::freeSharedMemory()
multiSlsDetector::multiSlsDetector(int id, bool verify, bool update)
: slsDetectorUtils(),
detId(id),
sharedMemory(0),
thisMultiDetector(0),
client_downstream(false),
threadpool(0)
{ {
// Detach Memory address bool created = initSharedMemory(verify, update);
for (int id = 0; id < thisMultiDetector->numberOfDetectors; ++id) { initializeDetectorStructure(created, verify, update);
if (detectors[id])
detectors[id]->freeSharedMemory();
}
if (shmdt(thisMultiDetector) == -1) { getNMods();
perror("shmdt failed\n"); getMaxMods();
return FAIL; if (createThreadPool() == FAIL)
} exit(-1);
#ifdef VERBOSE
printf("Shared memory %d detached\n", shmId);
#endif
// remove shared memory
if (shmctl(shmId, IPC_RMID, 0) == -1) {
perror("shmctl(IPC_RMID) failed\n");
return FAIL;
}
printf("Shared memory %d deleted\n", shmId);
return OK;
} }
int multiSlsDetector::initSharedMemory(int id = 0)
{
key_t mem_key = DEFAULT_SHM_KEY + MAXDET + id;
int shm_id;
int sz;
sz = sizeof(sharedMultiSlsDetector); multiSlsDetector::~multiSlsDetector(){
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
delete(*it);
}
detectors.clear();
#ifdef VERBOSE if (sharedMemory) {
std::cout << "multiSlsDetector: Size of shared memory is " << sz << " - id " << mem_key << std::endl; sharedMemory->UnmapSharedMemory(thisMultiDetector);
#endif delete sharedMemory;
shm_id = shmget(mem_key, sz, IPC_CREAT | 0666); // allocate shared memory }
if (shm_id < 0) { for (int i = 0; i < MAXDET; ++i) {
std::cout << "*** shmget error (server) ***" << shm_id << std::endl; if (zmqSocket[i]) {
return shm_id; delete zmqSocket[i];
}
} }
destroyThreadPool();
/**
thisMultiDetector pointer is set to the memory address of the shared memory
*/
thisMultiDetector = (sharedMultiSlsDetector*)shmat(shm_id, NULL, 0); /* attach */
if (thisMultiDetector == (void*)-1) {
std::cout << "*** shmat error (server) ***" << std::endl;
return shm_id;
}
/**
shm_id returns -1 is shared memory initialization fails
*/
return shm_id;
} }
slsDetector* multiSlsDetector::getSlsDetector(unsigned int pos) {
if (pos >= 0 && pos < detectors.size()) {
return detectors[pos];
}
return 0;
}
void multiSlsDetector::freeSharedMemory(int multiId) {
// get number of detectors
int numDetectors = 0;
SharedMemory* shm = new SharedMemory(multiId, -1);
std::string shmname = shm->GetName();
// shm not created before
if (SharedMemory::IsExisting(shmname)) {
sharedMultiDet* mdet = (sharedMultiSlsDetector*)shm->OpenSharedMemory(
sizeof(sharedMultiSlsDetector), false);
numDetectors = mdet->numberOfDetectors;
shm->UnmapSharedMemory(mdet);
shm->RemoveSharedMemory();
}
delete shm;
for (int i = 0; i < numDetectors; ++i) {
SharedMemory* shm = new SharedMemory(multiId, i);
shm->RemoveSharedMemory();
delete shm;
}
}
void multiSlsDetector::freeSharedMemory() {
// single detector vector
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
(*it)->freeSharedMemory();
delete (*it);
}
detectors.clear();
// multi detector
if (sharedMemory) {
sharedMemory->RemoveSharedMemory();
delete sharedMemory;
}
thisMultiDetector = 0;
}
std::string multiSlsDetector::getUserDetails() {
std::ostringstream sstream;
if (!detectors.size()) {
return std::string("none");
}
//hostname
sstream << "\nHostname: " << getHostname();
//type
sstream<< "\nType: ";
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it)
sstream<< (*it)->sgetDetectorsType() << "+"; /*change funtion signature without argument*/
//PID
sstream << "\nPID: " << thisMultiDetector->lastPID
//user
<< "\nUser: " << thisMultiDetector->lastUser
<< "\nDate: " << thisMultiDetector->lastDate << endl;
string s = sstream.str();
return s;
}
bool multiSlsDetector::initSharedMemory(bool verify, bool update) {
// clear
if (sharedMemory)
delete sharedMemory;
thisMultiDetector = 0;
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
delete(*it);
}
detectors.clear();
// create/open shm and map to structure
size_t sz = sizeof(sharedMultiSlsDetector);
bool created = false;
sharedMemory = new SharedMemory(detId, -1);
if (SharedMemory::IsExisting(sharedMemory->GetName())) {
thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->OpenSharedMemory(sz, verify);
if (verify && thisMultiDetector->shmversion != MULTI_SHMVERSION) {
cprintf(RED, "Multi shared memory version mismatch "
"(expected 0x%x but got 0x%x)\n",
MULTI_SHMVERSION, thisMultiDetector->shmversion);
throw SharedMemoryException();
}
} else {
try {
thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->CreateSharedMemory(sz);
created = true;
} catch(...) {
sharedMemory->RemoveSharedMemory();
thisMultiDetector = 0;
throw;
}
}
return created;
}
void multiSlsDetector::initializeDetectorStructure(bool created, bool verify, bool update) {
// set up new structure
if (created) {
thisMultiDetector->shmversion = MULTI_SHMVERSION;
thisMultiDetector->numberOfDetectors = 0;
thisMultiDetector->numberOfDetector[X] = 0;
thisMultiDetector->numberOfDetector[Y] = 0;
thisMultiDetector->onlineFlag = 1;
stoppedFlag = 0;
masterPosition = -1;
syncMode;
dataBytes = 0;
dataBytesInclGapPixels = 0;
numberOfChannels = 0;
numberOfChannel[X] = 0;
numberOfChannel[Y] = 0;
numberOfChannelInclGapPixels[X] = 0;
numberOfChannelInclGapPixels[Y] = 0;
maxNumberOfChannels = 0;
maxNumberOfChannel[X] = 0;
maxNumberOfChannel[Y] = 0;
maxNumberOfChannelInclGapPixels[X] = 0;
maxNumberOfChannelInclGapPixels[Y] = 0;
maxNumberOfChannelsPerDetector[X] = 0;
maxNumberOfChannelsPerDetector[Y] = 0;
int64_t timerValue[MAX_TIMERS];
detectorSettings currentSettings;
currentThresholdEV;
progressIndex = 0;
totalProgress = 1;
fileIndex = 0;
strncpy(thisMultiDetector->fileName, "run", MAX_STR_LENGTH);
strncpy(thisMultiDetector->filePath, "/", MAX_STR_LENGTH);
framesPerFile = 1;
fileFormat fileFormatType = ASCII;
correctionMask = (1 << WRITE_FILE) | (1 << OVERWRITE_FILE);
threadedProcessing;
tDead = 0;
strncpy(flatFieldDir, getenv("HOME"), MAX_STR_LENGTH);
strncpy(flatFieldFile, "none", MAX_STR_LENGTH);
strncpy(thisMultiDetector->badChanFile, "none", MAX_STR_LENGTH);
angConvFile[MAX_STR_LENGTH];
angDirection;
fineOffset;
globalOffset;
binSize;
sampleDisplacement[2];
numberOfPositions;
detPositions[MAXPOS];
actionMask;
mystring actionScript[MAX_ACTIONS];
mystring actionParameter[MAX_ACTIONS];
scanMode[MAX_SCAN_LEVELS];
mystring scanScript[MAX_SCAN_LEVELS];
mystring scanParameter[MAX_SCAN_LEVELS];
nScanSteps[MAX_SCAN_LEVELS];
mysteps scanSteps[MAX_SCAN_LEVELS];
scanPrecision[MAX_SCAN_LEVELS];
acquiringFlag;
externalgui;
receiverOnlineFlag;
receiver_upstream;
}
// get objects from single det shared memory (open)
for (int i = 0; i < thisMultiDetector->numberOfDetectors; i++) {
slsDetector* sdet = new slsDetector(detId, i, verify, this);
detectors.push_back(sdet);
}
//update user details
if (update) {
thisMultiDetector->lastPID = getpid();
memset(thisMultiDetector->lastUser, 0, SHORT_STRING_LENGTH);
memset(thisMultiDetector->lastDate, 0, SHORT_STRING_LENGTH);
try {
strncpy(thisMultiDetector->lastUser, exec("whoami").c_str(), SHORT_STRING_LENGTH);
strncpy(thisMultiDetector->lastDate, exec("date").c_str(), DATE_LENGTH);
} catch(...) {
strncpy(thisMultiDetector->lastUser, exec("errorreading").c_str(), SHORT_STRING_LENGTH);
strncpy(thisMultiDetector->lastDate, exec("errorreading").c_str(), SHORT_STRING_LENGTH);
}
}
}
void multiSlsDetector::AddSingleDetector (std::string s) {
cout << "Adding detector " << s << endl;
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
if ((*it)->GetHostname() == s) {
cout << "Detector " << s << "already part of the multiDetector!" << endl
<< "Remove it before adding it back in a new position!" << endl;
return;
}
}
//check entire shared memory if it doesnt exist?? needed?
//could be that detectors not loaded completely cuz of crash in new slsdetector in initsharedmemory
// get type by connecting
detectorType type = slsDetector::GetDetectorTypeFromDetector(s, DEFAULT_PORTNO);
if (type == GENERIC) {
cout << "Detector " << s << "does not exist in shared memory "
"and could not connect to it to determine the type!" << endl;
setErrorMask(getErrorMask() | MULTI_DETECTORS_NOT_ADDED);
appendNotAddedList(name);
return;
}
int pos = detectors.size();
slsDetector* sdet = new slsDetector(type, detId, pos, false, this);
detectors.push_back(sdet);
detectors[pos]->SetHostname(s);
detectors[pos]->SetOnline(1);
++thisMultiDetector->numberOfDetectors;
}
std::string multiSlsDetector::exec(const char* cmd) {
int bufsize = 1char buffer[bufsize];
std::string result = "";
FILE* pipe = popen(cmd, "r");
if (!pipe) throw std::exception();
try {
while (!feof(pipe)) {
if (fgets(buffer, bufsize, pipe) != NULL)
result += buffer;
}
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
result.erase(result.find_last_not_of(" \t\n\r")+1);
return result;
}
multiSlsDetector::multiSlsDetector(int id) multiSlsDetector::multiSlsDetector(int id)
: slsDetectorUtils() : slsDetectorUtils()
, shmId(-1) , shmId(-1)
@ -103,57 +350,14 @@ multiSlsDetector::multiSlsDetector(int id)
} }
if (thisMultiDetector->alreadyExisting == 0) { if (thisMultiDetector->alreadyExisting == 0) {
thisMultiDetector->onlineFlag = ONLINE_FLAG;
thisMultiDetector->receiverOnlineFlag = OFFLINE_FLAG; thisMultiDetector->receiverOnlineFlag = OFFLINE_FLAG;
thisMultiDetector->numberOfDetectors = 0;
thisMultiDetector->numberOfDetector[X] = 0;
thisMultiDetector->numberOfDetector[Y] = 0;
for (int id = 0; id < MAXDET; ++id) {
thisMultiDetector->detectorIds[id] = -1;
thisMultiDetector->offsetX[id] = 0;
thisMultiDetector->offsetY[id] = 0;
}
thisMultiDetector->masterPosition = -1;
thisMultiDetector->dataBytes = 0;
thisMultiDetector->dataBytesInclGapPixels = 0;
thisMultiDetector->numberOfChannels = 0;
thisMultiDetector->numberOfChannel[X] = 0;
thisMultiDetector->numberOfChannel[Y] = 0;
thisMultiDetector->numberOfChannelInclGapPixels[X] = 0;
thisMultiDetector->numberOfChannelInclGapPixels[Y] = 0;
thisMultiDetector->maxNumberOfChannels = 0;
thisMultiDetector->maxNumberOfChannel[X] = 0;
thisMultiDetector->maxNumberOfChannel[Y] = 0;
thisMultiDetector->maxNumberOfChannelInclGapPixels[X] = 0;
thisMultiDetector->maxNumberOfChannelInclGapPixels[Y] = 0;
thisMultiDetector->maxNumberOfChannelsPerDetector[X] = -1;
thisMultiDetector->maxNumberOfChannelsPerDetector[Y] = -1;
/** set trimDsdir, calDir and filePath to default to root directory*/
strcpy(thisMultiDetector->filePath, "/");
/** set fileName to default to run*/
strcpy(thisMultiDetector->fileName, "run");
/** set fileIndex to default to 0*/
thisMultiDetector->fileIndex = 0;
/** set frames per file to default to 1*/
thisMultiDetector->framesPerFile = 1;
/** set fileFormat to default to ascii*/
thisMultiDetector->fileFormatType = ASCII;
/** set progress Index to default to 0*/
thisMultiDetector->progressIndex = 0;
/** set total number of frames to be acquired to default to 1*/
thisMultiDetector->totalProgress = 1;
/** set correction mask to 0*/
thisMultiDetector->correctionMask = 1 << WRITE_FILE;
thisMultiDetector->correctionMask |= (1 << OVERWRITE_FILE);
/** set deat time*/
thisMultiDetector->tDead = 0;
/** sets bad channel list file to none */
strcpy(thisMultiDetector->badChanFile, "none");
/** sets flat field correction directory */ /** sets flat field correction directory */
strcpy(thisMultiDetector->flatFieldDir, getenv("HOME")); strcpy(thisMultiDetector->flatFieldDir, getenv("HOME"));
/** sets flat field correction file */ /** sets flat field correction file */
@ -175,7 +379,7 @@ multiSlsDetector::multiSlsDetector(int id)
strcpy(thisMultiDetector->angConvFile, "none"); strcpy(thisMultiDetector->angConvFile, "none");
/** set binsize*/ /** set binsize*/
thisMultiDetector->binSize = 0.001; thisMultiDetector->binSize = 0.001;
thisMultiDetector->stoppedFlag = 0;
thisMultiDetector->threadedProcessing = 1; thisMultiDetector->threadedProcessing = 1;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,165 @@
#include "SharedMemory.h"
#include "sls_detector_exceptions.h"
#include "ansi.h"
#include <iostream>
#include <stdio.h> // printf
#include <cerrno> // errno
#include <cstring> // strerror
#include <unistd.h>
#include <fcntl.h> // O_CREAT, O_TRUNC..
#include <sys/stat.h> // fstat
#include <sys/mman.h> // shared memory
#include <sstream>
SharedMemory::SharedMemory(int multiId, int singleId):
fd(-1),
shmSize(0)
{
name = ConstructSharedMemoryName(multiId, singleId);
}
SharedMemory::~SharedMemory(){
if (fd >= 0)
close(fd);
}
bool SharedMemory::IsExisting(std::string name) {
bool ret = true;
int fd = shm_open(name.c_str(), O_RDWR, 0);
if ((fd < 0) && (errno == ENOENT)) {
ret = false;
}
close(fd);
return ret;
}
std::string SharedMemory::GetName() {
return name;
}
void* SharedMemory::CreateSharedMemory(size_t sz){
// create
fd = shm_open(name.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
cprintf(RED, "Error: Create shared memory %s failed: %s\n",
name.c_str(), strerror(errno));
throw SharedMemoryException();
}
// resize
if (ftruncate(fd, sz) < 0) {
cprintf(RED, "Error: Create shared memory %s failed at ftruncate: %s\n",
name.c_str(), strerror(errno));
close(fd);
throw SharedMemoryException();
}
// map
return MapSharedMemory(sz);
}
void* SharedMemory::OpenSharedMemory(size_t sz, bool verify){
// open
fd = shm_open(name.c_str(), O_RDWR, 0);
if (fd < 0) {
cprintf(RED, "Error: Open existing shared memory %s failed: %s\n",
name.c_str(), strerror(errno));
throw SharedMemoryException();
}
// verification required and size does not match
if (verify)
VerifySizeMatch(sz);
// map
return MapSharedMemory(sz);
}
void SharedMemory::UnmapSharedMemory(void* addr) {
if (munmap(addr, shmSize) < 0) {
cprintf(RED, "Error: Unmapping shared memory %s failed: %s\n",
name.c_str(), strerror(errno));
close(fd);
throw SharedMemoryException();
}
}
void SharedMemory::RemoveSharedMemory() {
RemoveSharedMemory(name.c_str());
}
void* SharedMemory::MapSharedMemory(size_t sz) {
void* addr = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
cprintf(RED, "Error: Mapping shared memory %s failed: %s\n",
name.c_str(), strerror(errno));
close(fd);
throw SharedMemoryException();
}
shmSize = sz;
close(fd);
return addr;
}
std::string SharedMemory::ConstructSharedMemoryName(int multiId, int singleId) {
stringstream ss;
if (singleId < 0)
ss << "/slsDetectorPackage_multi_" << multiId;
else
ss << "/slsDetectorPackage_multi_" << multiId << "_single_" << singleId;
std::string temp = ss.str();
if (temp.length() > NAME_MAX) {
cprintf(RED, "Error: Shared memory initialization %s failed: %s\n",
name.c_str(), strerror(errno));
throw SharedMemoryException();
}
return temp;
}
int SharedMemory::VerifySizeMatch(size_t expectedSize) {
struct stat sb;
// could not fstat
if (fstat(fd, &sb) < 0) {
cprintf(RED, "Error: Could not verify existing shared memory %s size match "
"(could not fstat): %s\n", name.c_str(), strerror(errno));
close(fd);
throw SharedMemoryException();
}
//size does not match
long unsigned int sz = (long unsigned int)sb.st_size;
if (sz != expectedSize) {
cprintf(RED, "Warning: Existing shared memory %s size does not match.\n",
name.c_str());
#ifdef VERBOSE
cprintf(RED, " Expected %ld, found %ld\n", expectedSize, sz);
#endif
throw SharedMemoryException();
return 1;
}
return 0;
}
void SharedMemory::RemoveSharedMemory(std::string name) {
if (shm_unlink(name.c_str()) < 0) {
// silent exit if shm did not exist anyway
if (errno == ENOENT)
return;
cprintf(RED, "Error: Free Shared Memory %s Failed: %s\n",
name.c_str(), strerror(errno));
throw SharedMemoryException();
}
printf("Shared memory deleted %s \n", name.c_str());
}

View File

@ -0,0 +1,117 @@
#pragma once
/************************************************
* @file SharedMemory.h
* @short functions basic implemenation of
* shared memory
***********************************************/
/**
*@short functions basic implemenation of shared memory
*/
#include <iostream>
#include <string>
class SharedMemory{
public:
/**
* Constructor
* creates the single/multi detector shared memory name
* @param multiId multi detector id
* @param singleId sls detector id, -1 if a multi detector shared memory
*/
SharedMemory(int multiId, int singleId);
/**
* Destructor
*/
~SharedMemory();
/**
* Verify if it exists
* @param name of shared memory
* @return true if exists, else false
*/
static bool IsExisting(std::string name);
/**
* Get shared memory name
*/
std::string GetName();
/**
* Create Shared memory and call MapSharedMemory to map it to an address
* throws a SharedMemoryException exception on failure to create, ftruncate or map
* @param sz of shared memory
* @param addr double pointer to address to be mapped
*/
void* CreateSharedMemory(size_t sz);
/**
* Open existing Shared memory and call MapSharedMemory to map it to an address
* throws a SharedMemoryException exception on failure to open, incorrect size if verify true, or map
* @param sz of shared memory
* @param addr double pointer to address to be mapped
* @param verify true to verify if the size matches existing one and return fail if does not match
*/
void* OpenSharedMemory(size_t sz, bool verify = true);
/**
* Unmap shared memory from an address
* throws a SharedMemoryException exception on failure
* @param addr double pointer to address to be mapped
*/
void UnmapSharedMemory(void* addr);
/**
* Remove existing Shared memory
*/
void RemoveSharedMemory();
/**
* Maximum length of name as from man pages
*/
static const int NAME_MAX = 255;
private:
/**
* Create Shared memory name
* throws exception if name created is longer than required 255(manpages)
* @param multiId multi detector id
* @param singleId sls detector id, -1 if a multi detector shared memory
* @returns shared memory name
*/
std::string ConstructSharedMemoryName(int multiId, int singleId);
/**
* Map shared memory to an address
* throws a SharedMemoryException exception on failure
* @param addr double pointer to address to be mapped
* @param sz of shared memory
*/
//template <typename myType>
// void MapSharedMemory(myType*& addr, size_t sz);
void* MapSharedMemory(size_t sz);
/**
* Verify if existing shared memory size matches expected size
* @param sz expected size of shared memory, replaced with smaller size if size does not match
* @return 0 for success, 1 for fail
*/
int VerifySizeMatch(size_t expectedSize);
/**
* Remove existing Shared memory
* @param name name of shared memory (should be less than NAME_MAX)
*/
void RemoveSharedMemory(std::string name);
/** Shared memory name */
std::string name;
/** File descriptor */
int fd;
/** shm size */
size_t shmSize;
};

View File

@ -262,7 +262,7 @@ slsDetector::slsDetector(int pos, detectorType type, int id, multiSlsDetector *p
} }
slsDetector::~slsDetector(){ slsDetector:slsDetector(){
// Detach Memory address // Detach Memory address
if (shmdt(thisDetector) == -1) { if (shmdt(thisDetector) == -1) {