Merge branch 'shm' into refactor

This commit is contained in:
maliakal_d 2019-03-13 15:21:12 +01:00
commit 75ce111344
11 changed files with 1230 additions and 1137 deletions

View File

@ -10,42 +10,12 @@
#include "sls_detector_funcs.h" #include "sls_detector_funcs.h"
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#define VERBOSE #define VERBOSE
int main() { int main() {
// const std::string hostname = "beb083";
// auto d = slsDetector(hostname);
// d.setOnline(1);
// std::cout << "type: " << d.getDetectorTypeAsString() << '\n';
// std::cout << "hostname: " << d.getHostname() << '\n';
// std::cout << "receiver: " << d.getReceiverOnline() << '\n';
// std::cout << "control: " << d.getControlPort() << '\n';
// std::cout << "stop: " << d.getStopPort() << '\n';
// std::cout << "receiver: " << d.getReceiverPort() << '\n';
// std::cout << "exptime: " << d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME) << '\n';
// auto d2 = slsDetector(type, 0, 1);
// d2.setHostname("beb098");.
// auto d2 = slsDetector();
// std::cout << "hn: " << d2.getHostname() << '\n';
// sls::Timer t;
// for (int i = 0; i != 100; ++i) {
// int fnum = 1;
// int ret = slsDetectorDefs::FAIL;
// slsDetectorDefs::detectorType retval = slsDetectorDefs::detectorType::GENERIC;
// auto cs = sls::ClientSocket("beb083", 1952);
// cs.sendData(reinterpret_cast<char *>(&fnum), sizeof(fnum));
// cs.receiveData(reinterpret_cast<char *>(&ret), sizeof(ret));
// cs.receiveData(reinterpret_cast<char *>(&retval), sizeof(retval));
// std::cout << "retval: " << retval << '\n';
// }
// t.print_elapsed();
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
set(SOURCES set(SOURCES
multiSlsDetector/multiSlsDetector.cpp multiSlsDetector/multiSlsDetector.cpp
sharedMemory/SharedMemory.cpp # sharedMemory/SharedMemory.cpp
slsDetector/slsDetectorUsers.cpp slsDetector/slsDetectorUsers.cpp
slsDetector/slsDetectorCommand.cpp slsDetector/slsDetectorCommand.cpp
slsDetector/slsDetector.cpp slsDetector/slsDetector.cpp
@ -49,6 +49,10 @@ if(DOXYGEN_FOUND)
) )
endif() endif()
if (SLS_USE_TESTS)
add_subdirectory(tests)
endif(SLS_USE_TESTS)
install(TARGETS slsDetectorShared install(TARGETS slsDetectorShared
EXPORT "${TARGETS_EXPORT_NAME}" EXPORT "${TARGETS_EXPORT_NAME}"

View File

@ -31,12 +31,7 @@ multiSlsDetector::multiSlsDetector(int id, bool verify, bool update)
setupMultiDetector(verify, update); setupMultiDetector(verify, update);
} }
multiSlsDetector::~multiSlsDetector() { multiSlsDetector::~multiSlsDetector() = default;
if (sharedMemory) {
sharedMemory->UnmapSharedMemory(thisMultiDetector);
delete sharedMemory;
}
}
void multiSlsDetector::setupMultiDetector(bool verify, bool update) { void multiSlsDetector::setupMultiDetector(bool verify, bool update) {
initSharedMemory(verify); initSharedMemory(verify);
@ -197,21 +192,21 @@ void multiSlsDetector::setErrorMaskFromAllDetectors() {
} }
void multiSlsDetector::setAcquiringFlag(bool b) { void multiSlsDetector::setAcquiringFlag(bool b) {
thisMultiDetector->acquiringFlag = b; sharedMemory()->acquiringFlag = b;
} }
bool multiSlsDetector::getAcquiringFlag() const { bool multiSlsDetector::getAcquiringFlag() const {
return thisMultiDetector->acquiringFlag; return sharedMemory()->acquiringFlag;
} }
bool multiSlsDetector::isAcquireReady() { bool multiSlsDetector::isAcquireReady() {
if (thisMultiDetector->acquiringFlag) { if (sharedMemory()->acquiringFlag) {
FILE_LOG(logWARNING) << "Acquire has already started. " FILE_LOG(logWARNING) << "Acquire has already started. "
"If previous acquisition terminated unexpectedly, " "If previous acquisition terminated unexpectedly, "
"reset busy flag to restart.(sls_detector_put busy 0)"; "reset busy flag to restart.(sls_detector_put busy 0)";
return FAIL; return FAIL;
} }
thisMultiDetector->acquiringFlag = true; sharedMemory()->acquiringFlag = true;
return OK; return OK;
} }
@ -249,23 +244,18 @@ void multiSlsDetector::freeSharedMemory(int multiId, int detPos) {
return; return;
} }
// multi // multi - get number of detectors from shm
// get number of detectors SharedMemory<sharedMultiSlsDetector> multiShm(multiId, -1);
int numDetectors = 0; int numDetectors = 0;
auto shm = SharedMemory(multiId, -1);
// get number of detectors from multi shm if (multiShm.IsExisting()) {
if (shm.IsExisting()) { multiShm.OpenSharedMemory();
sharedMultiSlsDetector *mdet = numDetectors = multiShm()->numberOfDetectors;
(sharedMultiSlsDetector *)shm.OpenSharedMemory( multiShm.RemoveSharedMemory();
sizeof(sharedMultiSlsDetector));
numDetectors = mdet->numberOfDetectors;
shm.UnmapSharedMemory(mdet);
shm.RemoveSharedMemory();
} }
for (int i = 0; i < numDetectors; ++i) { for (int i = 0; i < numDetectors; ++i) {
auto shm = SharedMemory(multiId, i); SharedMemory<sharedSlsDetector> shm(multiId, i);
shm.RemoveSharedMemory(); shm.RemoveSharedMemory();
} }
} }
@ -286,17 +276,7 @@ void multiSlsDetector::freeSharedMemory(int detPos) {
detectors.clear(); detectors.clear();
// clear multi detector shm // clear multi detector shm
if (sharedMemory) { sharedMemory.RemoveSharedMemory();
if (thisMultiDetector) {
sharedMemory->UnmapSharedMemory(thisMultiDetector);
thisMultiDetector = nullptr;
}
sharedMemory->RemoveSharedMemory();
delete sharedMemory;
sharedMemory = nullptr;
}
// zmq
client_downstream = false; client_downstream = false;
} }
@ -312,78 +292,56 @@ std::string multiSlsDetector::getUserDetails() {
sstream << d->getDetectorTypeAsString() << "+"; sstream << d->getDetectorTypeAsString() << "+";
} }
sstream << "\nPID: " << thisMultiDetector->lastPID sstream << "\nPID: " << sharedMemory()->lastPID
<< "\nUser: " << thisMultiDetector->lastUser << "\nUser: " << sharedMemory()->lastUser
<< "\nDate: " << thisMultiDetector->lastDate << std::endl; << "\nDate: " << sharedMemory()->lastDate << std::endl;
return sstream.str(); return sstream.str();
} }
/* /*
* pre: sharedMemory=0, thisMultiDetector = 0, detectors.size() = 0 * pre: sharedMemory=0, sharedMemory() = 0, detectors.size() = 0
* exceptions are caught in calling function, shm unmapped and deleted
*/ */
void multiSlsDetector::initSharedMemory(bool verify) { void multiSlsDetector::initSharedMemory(bool verify) {
try { sharedMemory = SharedMemory<sharedMultiSlsDetector>(detId, -1);
// shared memory object with name if (!sharedMemory.IsExisting()) {
sharedMemory = new SharedMemory(detId, -1); sharedMemory.CreateSharedMemory();
size_t sz = sizeof(sharedMultiSlsDetector);
// create
if (!sharedMemory->IsExisting()) {
thisMultiDetector =
(sharedMultiSlsDetector *)sharedMemory->CreateSharedMemory(sz);
initializeDetectorStructure(); initializeDetectorStructure();
} }
// open and verify version
else { else {
thisMultiDetector = sharedMemory.OpenSharedMemory();
(sharedMultiSlsDetector *)sharedMemory->OpenSharedMemory(sz); if (verify && sharedMemory()->shmversion != MULTI_SHMVERSION) {
if (verify && thisMultiDetector->shmversion != MULTI_SHMVERSION) {
FILE_LOG(logERROR) << "Multi shared memory (" << detId << ") version mismatch " FILE_LOG(logERROR) << "Multi shared memory (" << detId << ") version mismatch "
"(expected 0x" "(expected 0x"
<< std::hex << MULTI_SHMVERSION << " but got 0x" << thisMultiDetector->shmversion << std::dec; << std::hex << MULTI_SHMVERSION << " but got 0x" << sharedMemory()->shmversion << std::dec;
throw SharedMemoryException(); throw SharedMemoryException();
} }
} }
} catch (...) {
if (sharedMemory) {
// unmap
if (thisMultiDetector) {
sharedMemory->UnmapSharedMemory(thisMultiDetector);
thisMultiDetector = nullptr;
}
// delete
delete sharedMemory;
sharedMemory = nullptr;
}
throw;
}
} }
void multiSlsDetector::initializeDetectorStructure() { void multiSlsDetector::initializeDetectorStructure() {
thisMultiDetector->shmversion = MULTI_SHMVERSION; sharedMemory()->shmversion = MULTI_SHMVERSION;
thisMultiDetector->numberOfDetectors = 0; sharedMemory()->numberOfDetectors = 0;
thisMultiDetector->numberOfDetector[X] = 0; sharedMemory()->numberOfDetector[X] = 0;
thisMultiDetector->numberOfDetector[Y] = 0; sharedMemory()->numberOfDetector[Y] = 0;
thisMultiDetector->onlineFlag = 1; sharedMemory()->onlineFlag = 1;
thisMultiDetector->stoppedFlag = 0; sharedMemory()->stoppedFlag = 0;
thisMultiDetector->dataBytes = 0; sharedMemory()->dataBytes = 0;
thisMultiDetector->dataBytesInclGapPixels = 0; sharedMemory()->dataBytesInclGapPixels = 0;
thisMultiDetector->numberOfChannels = 0; sharedMemory()->numberOfChannels = 0;
thisMultiDetector->numberOfChannel[X] = 0; sharedMemory()->numberOfChannel[X] = 0;
thisMultiDetector->numberOfChannel[Y] = 0; sharedMemory()->numberOfChannel[Y] = 0;
thisMultiDetector->numberOfChannelInclGapPixels[X] = 0; sharedMemory()->numberOfChannelInclGapPixels[X] = 0;
thisMultiDetector->numberOfChannelInclGapPixels[Y] = 0; sharedMemory()->numberOfChannelInclGapPixels[Y] = 0;
thisMultiDetector->maxNumberOfChannelsPerDetector[X] = 0; sharedMemory()->maxNumberOfChannelsPerDetector[X] = 0;
thisMultiDetector->maxNumberOfChannelsPerDetector[Y] = 0; sharedMemory()->maxNumberOfChannelsPerDetector[Y] = 0;
for (int64_t &i : thisMultiDetector->timerValue) { for (int64_t &i : sharedMemory()->timerValue) {
i = 0; i = 0;
} }
thisMultiDetector->acquiringFlag = false; sharedMemory()->acquiringFlag = false;
thisMultiDetector->receiverOnlineFlag = OFFLINE_FLAG; sharedMemory()->receiverOnlineFlag = OFFLINE_FLAG;
thisMultiDetector->receiver_upstream = false; sharedMemory()->receiver_upstream = false;
} }
void multiSlsDetector::initializeMembers(bool verify) { void multiSlsDetector::initializeMembers(bool verify) {
@ -391,7 +349,7 @@ void multiSlsDetector::initializeMembers(bool verify) {
zmqSocket.clear(); zmqSocket.clear();
// get objects from single det shared memory (open) // get objects from single det shared memory (open)
for (int i = 0; i < thisMultiDetector->numberOfDetectors; i++) { for (int i = 0; i < sharedMemory()->numberOfDetectors; i++) {
try { try {
detectors.push_back( detectors.push_back(
sls::make_unique<slsDetector>(detId, i, verify)); sls::make_unique<slsDetector>(detId, i, verify));
@ -406,15 +364,15 @@ void multiSlsDetector::initializeMembers(bool verify) {
} }
void multiSlsDetector::updateUserdetails() { void multiSlsDetector::updateUserdetails() {
thisMultiDetector->lastPID = getpid(); sharedMemory()->lastPID = getpid();
memset(thisMultiDetector->lastUser, 0, SHORT_STRING_LENGTH); memset(sharedMemory()->lastUser, 0, SHORT_STRING_LENGTH);
memset(thisMultiDetector->lastDate, 0, SHORT_STRING_LENGTH); memset(sharedMemory()->lastDate, 0, SHORT_STRING_LENGTH);
try { try {
sls::strcpy_safe(thisMultiDetector->lastUser, exec("whoami").c_str()); sls::strcpy_safe(sharedMemory()->lastUser, exec("whoami").c_str());
sls::strcpy_safe(thisMultiDetector->lastDate, exec("date").c_str()); sls::strcpy_safe(sharedMemory()->lastDate, exec("date").c_str());
} catch (...) { } catch (...) {
sls::strcpy_safe(thisMultiDetector->lastUser, "errorreading"); sls::strcpy_safe(sharedMemory()->lastUser, "errorreading");
sls::strcpy_safe(thisMultiDetector->lastDate, "errorreading"); sls::strcpy_safe(sharedMemory()->lastDate, "errorreading");
} }
} }
@ -450,7 +408,7 @@ void multiSlsDetector::setHostname(const char *name, int detPos) {
// multi // multi
// this check is there only to allow the previous detsizechan command // this check is there only to allow the previous detsizechan command
if (thisMultiDetector->numberOfDetectors) { if (sharedMemory()->numberOfDetectors) {
FILE_LOG(logWARNING) << "There are already detector(s) in shared memory." FILE_LOG(logWARNING) << "There are already detector(s) in shared memory."
"Freeing Shared memory now."; "Freeing Shared memory now.";
freeSharedMemory(); freeSharedMemory();
@ -503,11 +461,11 @@ void multiSlsDetector::addSlsDetector(const std::string &hostname) {
int pos = (int)detectors.size(); int pos = (int)detectors.size();
detectors.push_back(sls::make_unique<slsDetector>(type, detId, pos, false)); detectors.push_back(sls::make_unique<slsDetector>(type, detId, pos, false));
thisMultiDetector->numberOfDetectors = detectors.size(); sharedMemory()->numberOfDetectors = detectors.size();
thisMultiDetector->dataBytes += detectors[pos]->getDataBytes(); sharedMemory()->dataBytes += detectors[pos]->getDataBytes();
thisMultiDetector->dataBytesInclGapPixels += sharedMemory()->dataBytesInclGapPixels +=
detectors[pos]->getDataBytesInclGapPixels(); detectors[pos]->getDataBytesInclGapPixels();
thisMultiDetector->numberOfChannels += sharedMemory()->numberOfChannels +=
detectors[pos]->getTotalNumberOfChannels(); detectors[pos]->getTotalNumberOfChannels();
detectors[pos]->setHostname(hostname); detectors[pos]->setHostname(hostname);
@ -541,12 +499,12 @@ int multiSlsDetector::getNumberOfDetectors() const {
} }
int multiSlsDetector::getNumberOfDetectors(dimension d) const { int multiSlsDetector::getNumberOfDetectors(dimension d) const {
return thisMultiDetector->numberOfDetector[d]; return sharedMemory()->numberOfDetector[d];
} }
void multiSlsDetector::getNumberOfDetectors(int &nx, int &ny) const { void multiSlsDetector::getNumberOfDetectors(int &nx, int &ny) const {
nx = thisMultiDetector->numberOfDetector[X]; nx = sharedMemory()->numberOfDetector[X];
ny = thisMultiDetector->numberOfDetector[Y]; ny = sharedMemory()->numberOfDetector[Y];
} }
int multiSlsDetector::getTotalNumberOfChannels(int detPos) { int multiSlsDetector::getTotalNumberOfChannels(int detPos) {
@ -556,7 +514,7 @@ int multiSlsDetector::getTotalNumberOfChannels(int detPos) {
} }
// multi // multi
return thisMultiDetector->numberOfChannels; return sharedMemory()->numberOfChannels;
} }
int multiSlsDetector::getTotalNumberOfChannels(dimension d, int detPos) { int multiSlsDetector::getTotalNumberOfChannels(dimension d, int detPos) {
@ -566,7 +524,7 @@ int multiSlsDetector::getTotalNumberOfChannels(dimension d, int detPos) {
} }
// multi // multi
return thisMultiDetector->numberOfChannel[d]; return sharedMemory()->numberOfChannel[d];
} }
int multiSlsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d, int multiSlsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d,
@ -577,16 +535,16 @@ int multiSlsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d,
} }
// multi // multi
return thisMultiDetector->numberOfChannelInclGapPixels[d]; return sharedMemory()->numberOfChannelInclGapPixels[d];
} }
int multiSlsDetector::getMaxNumberOfChannelsPerDetector(dimension d) { int multiSlsDetector::getMaxNumberOfChannelsPerDetector(dimension d) {
return thisMultiDetector->maxNumberOfChannelsPerDetector[d]; return sharedMemory()->maxNumberOfChannelsPerDetector[d];
} }
int multiSlsDetector::setMaxNumberOfChannelsPerDetector(dimension d, int i) { int multiSlsDetector::setMaxNumberOfChannelsPerDetector(dimension d, int i) {
thisMultiDetector->maxNumberOfChannelsPerDetector[d] = i; sharedMemory()->maxNumberOfChannelsPerDetector[d] = i;
return thisMultiDetector->maxNumberOfChannelsPerDetector[d]; return sharedMemory()->maxNumberOfChannelsPerDetector[d];
} }
int multiSlsDetector::getDetectorOffset(dimension d, int detPos) { int multiSlsDetector::getDetectorOffset(dimension d, int detPos) {
@ -601,22 +559,22 @@ void multiSlsDetector::updateOffsets() {
FILE_LOG(logDEBUG1) << "Updating Multi-Detector Offsets"; FILE_LOG(logDEBUG1) << "Updating Multi-Detector Offsets";
int offsetX = 0, offsetY = 0, numX = 0, numY = 0; int offsetX = 0, offsetY = 0, numX = 0, numY = 0;
int maxChanX = thisMultiDetector->maxNumberOfChannelsPerDetector[X]; int maxChanX = sharedMemory()->maxNumberOfChannelsPerDetector[X];
int maxChanY = thisMultiDetector->maxNumberOfChannelsPerDetector[Y]; int maxChanY = sharedMemory()->maxNumberOfChannelsPerDetector[Y];
int prevChanX = 0; int prevChanX = 0;
int prevChanY = 0; int prevChanY = 0;
bool firstTime = true; bool firstTime = true;
thisMultiDetector->numberOfChannel[X] = 0; sharedMemory()->numberOfChannel[X] = 0;
thisMultiDetector->numberOfChannel[Y] = 0; sharedMemory()->numberOfChannel[Y] = 0;
thisMultiDetector->numberOfDetector[X] = 0; sharedMemory()->numberOfDetector[X] = 0;
thisMultiDetector->numberOfDetector[Y] = 0; sharedMemory()->numberOfDetector[Y] = 0;
// gap pixels // gap pixels
int offsetX_gp = 0, offsetY_gp = 0, numX_gp = 0, numY_gp = 0; int offsetX_gp = 0, offsetY_gp = 0, numX_gp = 0, numY_gp = 0;
int prevChanX_gp = 0, prevChanY_gp = 0; int prevChanX_gp = 0, prevChanY_gp = 0;
thisMultiDetector->numberOfChannelInclGapPixels[X] = 0; sharedMemory()->numberOfChannelInclGapPixels[X] = 0;
thisMultiDetector->numberOfChannelInclGapPixels[Y] = 0; sharedMemory()->numberOfChannelInclGapPixels[Y] = 0;
for (size_t idet = 0; idet < detectors.size(); ++idet) { for (size_t idet = 0; idet < detectors.size(); ++idet) {
FILE_LOG(logDEBUG1) << "offsetX:" << offsetX << " prevChanX:" << prevChanX << " offsetY:" << offsetY << " prevChanY:" << prevChanY << " offsetX_gp:" << offsetX_gp << " prevChanX_gp:" << prevChanX_gp << " offsetY_gp:" << offsetY_gp << " prevChanY_gp:" << prevChanY_gp; FILE_LOG(logDEBUG1) << "offsetX:" << offsetX << " prevChanX:" << prevChanX << " offsetY:" << offsetY << " prevChanY:" << prevChanY << " offsetX_gp:" << offsetX_gp << " prevChanX_gp:" << prevChanX_gp << " offsetY_gp:" << offsetY_gp << " prevChanY_gp:" << prevChanY_gp;
@ -649,8 +607,8 @@ void multiSlsDetector::updateOffsets() {
detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X); detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X);
numY_gp += numY_gp +=
detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y); detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y);
++thisMultiDetector->numberOfDetector[X]; ++sharedMemory()->numberOfDetector[X];
++thisMultiDetector->numberOfDetector[Y]; ++sharedMemory()->numberOfDetector[Y];
FILE_LOG(logDEBUG1) << "incrementing in both direction"; FILE_LOG(logDEBUG1) << "incrementing in both direction";
} }
@ -668,8 +626,8 @@ void multiSlsDetector::updateOffsets() {
numY_gp += numY_gp +=
detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y); detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y);
// increment in y again only in the first column (else you double increment) // increment in y again only in the first column (else you double increment)
if (thisMultiDetector->numberOfDetector[X] == 1) if (sharedMemory()->numberOfDetector[X] == 1)
++thisMultiDetector->numberOfDetector[Y]; ++sharedMemory()->numberOfDetector[Y];
FILE_LOG(logDEBUG1) << "incrementing in y direction"; FILE_LOG(logDEBUG1) << "incrementing in y direction";
} }
@ -698,7 +656,7 @@ void multiSlsDetector::updateOffsets() {
numX += detectors[idet]->getTotalNumberOfChannels(X); numX += detectors[idet]->getTotalNumberOfChannels(X);
numX_gp += numX_gp +=
detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X); detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X);
++thisMultiDetector->numberOfDetector[X]; ++sharedMemory()->numberOfDetector[X];
FILE_LOG(logDEBUG1) << "incrementing in x direction"; FILE_LOG(logDEBUG1) << "incrementing in x direction";
} }
@ -716,28 +674,28 @@ void multiSlsDetector::updateOffsets() {
<< detectors[idet]->getDetectorOffset(Y) << ")"; << detectors[idet]->getDetectorOffset(Y) << ")";
// offsetY has been reset sometimes and offsetX the first time, // offsetY has been reset sometimes and offsetX the first time,
// but remember the highest values // but remember the highest values
if (numX > thisMultiDetector->numberOfChannel[X]) { if (numX > sharedMemory()->numberOfChannel[X]) {
thisMultiDetector->numberOfChannel[X] = numX; sharedMemory()->numberOfChannel[X] = numX;
} }
if (numY > thisMultiDetector->numberOfChannel[Y]) { if (numY > sharedMemory()->numberOfChannel[Y]) {
thisMultiDetector->numberOfChannel[Y] = numY; sharedMemory()->numberOfChannel[Y] = numY;
} }
if (numX_gp > thisMultiDetector->numberOfChannelInclGapPixels[X]) { if (numX_gp > sharedMemory()->numberOfChannelInclGapPixels[X]) {
thisMultiDetector->numberOfChannelInclGapPixels[X] = numX_gp; sharedMemory()->numberOfChannelInclGapPixels[X] = numX_gp;
} }
if (numY_gp > thisMultiDetector->numberOfChannelInclGapPixels[Y]) { if (numY_gp > sharedMemory()->numberOfChannelInclGapPixels[Y]) {
thisMultiDetector->numberOfChannelInclGapPixels[Y] = numY_gp; sharedMemory()->numberOfChannelInclGapPixels[Y] = numY_gp;
} }
} }
FILE_LOG(logDEBUG1) << "\n\tNumber of Channels in X direction:" << thisMultiDetector->numberOfChannel[X] << "\n\tNumber of Channels in Y direction:" << thisMultiDetector->numberOfChannel[Y] << "\n\tNumber of Channels in X direction with Gap Pixels:" << thisMultiDetector->numberOfChannelInclGapPixels[X] << "\n\tNumber of Channels in Y direction with Gap Pixels:" << thisMultiDetector->numberOfChannelInclGapPixels[Y]; FILE_LOG(logDEBUG1) << "\n\tNumber of Channels in X direction:" << sharedMemory()->numberOfChannel[X] << "\n\tNumber of Channels in Y direction:" << sharedMemory()->numberOfChannel[Y] << "\n\tNumber of Channels in X direction with Gap Pixels:" << sharedMemory()->numberOfChannelInclGapPixels[X] << "\n\tNumber of Channels in Y direction with Gap Pixels:" << sharedMemory()->numberOfChannelInclGapPixels[Y];
thisMultiDetector->numberOfChannels = sharedMemory()->numberOfChannels =
thisMultiDetector->numberOfChannel[0] * sharedMemory()->numberOfChannel[0] *
thisMultiDetector->numberOfChannel[1]; sharedMemory()->numberOfChannel[1];
for (auto &d : detectors) { for (auto &d : detectors) {
d->updateMultiSize(thisMultiDetector->numberOfDetector[0], d->updateMultiSize(sharedMemory()->numberOfDetector[0],
thisMultiDetector->numberOfDetector[1]); sharedMemory()->numberOfDetector[1]);
} }
} }
@ -750,9 +708,9 @@ int multiSlsDetector::setOnline(int value, int detPos) {
// multi // multi
if (value != GET_ONLINE_FLAG) { if (value != GET_ONLINE_FLAG) {
auto r = parallelCall(&slsDetector::setOnline, value); auto r = parallelCall(&slsDetector::setOnline, value);
thisMultiDetector->onlineFlag = sls::minusOneIfDifferent(r); sharedMemory()->onlineFlag = sls::minusOneIfDifferent(r);
} }
return thisMultiDetector->onlineFlag; return sharedMemory()->onlineFlag;
} }
std::string multiSlsDetector::checkOnline(int detPos) { std::string multiSlsDetector::checkOnline(int detPos) {
@ -1104,12 +1062,12 @@ int multiSlsDetector::stopAcquisition(int detPos) {
if (detPos >= 0) { if (detPos >= 0) {
// if only 1 detector, set flag to stop current acquisition // if only 1 detector, set flag to stop current acquisition
if (detectors.size() == 1) { if (detectors.size() == 1) {
thisMultiDetector->stoppedFlag = 1; sharedMemory()->stoppedFlag = 1;
} }
return detectors[detPos]->stopAcquisition(); return detectors[detPos]->stopAcquisition();
} else { } else {
thisMultiDetector->stoppedFlag = 1; sharedMemory()->stoppedFlag = 1;
auto r = parallelCall(&slsDetector::stopAcquisition); auto r = parallelCall(&slsDetector::stopAcquisition);
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL; return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
} }
@ -1196,7 +1154,7 @@ int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t, int detPos) {
<< "Cannot set number of frames, cycles, " << "Cannot set number of frames, cycles, "
"storage cells or measurements individually."; "storage cells or measurements individually.";
setErrorMask(getErrorMask() | MUST_BE_MULTI_CMD); setErrorMask(getErrorMask() | MUST_BE_MULTI_CMD);
return thisMultiDetector->timerValue[index]; return sharedMemory()->timerValue[index];
default: default:
break; break;
} }
@ -1227,7 +1185,7 @@ int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t, int detPos) {
} }
} }
thisMultiDetector->timerValue[index] = ret; sharedMemory()->timerValue[index] = ret;
return ret; return ret;
} }
@ -1395,16 +1353,16 @@ int multiSlsDetector::setDynamicRange(int dr, int detPos) {
int ret = sls::minusOneIfDifferent(r); int ret = sls::minusOneIfDifferent(r);
// update shm // update shm
int prevValue = thisMultiDetector->dataBytes; int prevValue = sharedMemory()->dataBytes;
int prevGValue = thisMultiDetector->dataBytesInclGapPixels; int prevGValue = sharedMemory()->dataBytesInclGapPixels;
thisMultiDetector->dataBytes = 0; sharedMemory()->dataBytes = 0;
thisMultiDetector->dataBytesInclGapPixels = 0; sharedMemory()->dataBytesInclGapPixels = 0;
thisMultiDetector->numberOfChannels = 0; sharedMemory()->numberOfChannels = 0;
for (auto &d : detectors) { for (auto &d : detectors) {
thisMultiDetector->dataBytes += d->getDataBytes(); sharedMemory()->dataBytes += d->getDataBytes();
thisMultiDetector->dataBytesInclGapPixels += sharedMemory()->dataBytesInclGapPixels +=
d->getDataBytesInclGapPixels(); d->getDataBytesInclGapPixels();
thisMultiDetector->numberOfChannels += d->getTotalNumberOfChannels(); sharedMemory()->numberOfChannels += d->getTotalNumberOfChannels();
} }
// for usability // for usability
@ -1427,8 +1385,8 @@ int multiSlsDetector::setDynamicRange(int dr, int detPos) {
// update offsets if there was a change FIXME:add dr to sls shm and check // update offsets if there was a change FIXME:add dr to sls shm and check
// that instead // that instead
if ((prevValue != thisMultiDetector->dataBytes) || if ((prevValue != sharedMemory()->dataBytes) ||
(prevGValue != thisMultiDetector->dataBytesInclGapPixels)) { (prevGValue != sharedMemory()->dataBytesInclGapPixels)) {
updateOffsets(); updateOffsets();
} }
@ -1955,7 +1913,6 @@ std::string multiSlsDetector::getAdditionalJsonParameter(const std::string &key,
return sls::concatenateIfDifferent(r); return sls::concatenateIfDifferent(r);
} }
int multiSlsDetector::setDetectorMinMaxEnergyThreshold(const int index, int value, int detPos) { int multiSlsDetector::setDetectorMinMaxEnergyThreshold(const int index, int value, int detPos) {
std::string parameter = (index ? "emax" : "emin"); std::string parameter = (index ? "emax" : "emin");
@ -1971,7 +1928,7 @@ int multiSlsDetector::setDetectorMinMaxEnergyThreshold(const int index, int valu
return stoi(result); return stoi(result);
} }
// not found or cannot scan integer // not found or cannot scan integer
catch(...) { catch (...) {
return -1; return -1;
} }
} }
@ -2064,7 +2021,7 @@ int multiSlsDetector::loadImageToDetector(imageType index,
// multi // multi
// read image for all // read image for all
int nch = thisMultiDetector->numberOfChannels; int nch = sharedMemory()->numberOfChannels;
short int imageVals[nch]; short int imageVals[nch];
if (readDataFile(fname, imageVals, nch) < nch * (int)sizeof(short int)) { if (readDataFile(fname, imageVals, nch) < nch * (int)sizeof(short int)) {
FILE_LOG(logERROR) << "Could not open file or not enough data in file " FILE_LOG(logERROR) << "Could not open file or not enough data in file "
@ -2093,7 +2050,7 @@ int multiSlsDetector::writeCounterBlockFile(const std::string &fname,
// multi // multi
// get image from all // get image from all
int nch = thisMultiDetector->numberOfChannels; int nch = sharedMemory()->numberOfChannels;
short int imageVals[nch]; short int imageVals[nch];
std::vector<int> r; std::vector<int> r;
for (size_t idet = 0; idet < detectors.size(); ++idet) { for (size_t idet = 0; idet < detectors.size(); ++idet) {
@ -2537,7 +2494,7 @@ int multiSlsDetector::enableGapPixels(int val, int detPos) {
// update data bytes incl gap pixels // update data bytes incl gap pixels
if (val != -1) { if (val != -1) {
auto r = serialCall(&slsDetector::getDataBytesInclGapPixels); auto r = serialCall(&slsDetector::getDataBytesInclGapPixels);
thisMultiDetector->dataBytesInclGapPixels = sls::sum(r); sharedMemory()->dataBytesInclGapPixels = sls::sum(r);
// update // update
updateOffsets(); updateOffsets();
@ -2744,9 +2701,9 @@ int multiSlsDetector::setReceiverOnline(int value, int detPos) {
// multi // multi
if (value != GET_ONLINE_FLAG) { if (value != GET_ONLINE_FLAG) {
auto r = parallelCall(&slsDetector::setReceiverOnline, value); auto r = parallelCall(&slsDetector::setReceiverOnline, value);
thisMultiDetector->receiverOnlineFlag = sls::minusOneIfDifferent(r); sharedMemory()->receiverOnlineFlag = sls::minusOneIfDifferent(r);
} }
return thisMultiDetector->receiverOnlineFlag; return sharedMemory()->receiverOnlineFlag;
} }
std::string multiSlsDetector::checkReceiverOnline(int detPos) { std::string multiSlsDetector::checkReceiverOnline(int detPos) {
@ -3084,8 +3041,8 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) {
void multiSlsDetector::readFrameFromReceiver() { void multiSlsDetector::readFrameFromReceiver() {
int nX = int nX =
thisMultiDetector->numberOfDetector[X]; // to copy data in multi module sharedMemory()->numberOfDetector[X]; // to copy data in multi module
int nY = thisMultiDetector int nY = sharedMemory()
->numberOfDetector[Y]; // for eiger, to reverse the data ->numberOfDetector[Y]; // for eiger, to reverse the data
bool gappixelsenable = false; bool gappixelsenable = false;
bool eiger = false; bool eiger = false;
@ -3233,8 +3190,8 @@ void multiSlsDetector::readFrameFromReceiver() {
// 4bit gap pixels // 4bit gap pixels
if (dynamicRange == 4 && gappixelsenable) { if (dynamicRange == 4 && gappixelsenable) {
int n = processImageWithGapPixels(multiframe, multigappixels); int n = processImageWithGapPixels(multiframe, multigappixels);
nPixelsX = thisMultiDetector->numberOfChannelInclGapPixels[X]; nPixelsX = sharedMemory()->numberOfChannelInclGapPixels[X];
nPixelsY = thisMultiDetector->numberOfChannelInclGapPixels[Y]; nPixelsY = sharedMemory()->numberOfChannelInclGapPixels[Y];
thisData = new detectorData(getCurrentProgress(), thisData = new detectorData(getCurrentProgress(),
currentFileName.c_str(), nPixelsX, currentFileName.c_str(), nPixelsX,
nPixelsY, multigappixels, n, nPixelsY, multigappixels, n,
@ -3290,12 +3247,12 @@ void multiSlsDetector::readFrameFromReceiver() {
int multiSlsDetector::processImageWithGapPixels(char *image, char *&gpImage) { int multiSlsDetector::processImageWithGapPixels(char *image, char *&gpImage) {
// eiger 4 bit mode // eiger 4 bit mode
int nxb = thisMultiDetector->numberOfDetector[X] * (512 + 3); int nxb = sharedMemory()->numberOfDetector[X] * (512 + 3);
int nyb = thisMultiDetector->numberOfDetector[Y] * (256 + 1); int nyb = sharedMemory()->numberOfDetector[Y] * (256 + 1);
int gapdatabytes = nxb * nyb; int gapdatabytes = nxb * nyb;
int nxchip = thisMultiDetector->numberOfDetector[X] * 4; int nxchip = sharedMemory()->numberOfDetector[X] * 4;
int nychip = thisMultiDetector->numberOfDetector[Y] * 1; int nychip = sharedMemory()->numberOfDetector[Y] * 1;
// allocate // allocate
if (gpImage == nullptr) { if (gpImage == nullptr) {
@ -3902,20 +3859,20 @@ void multiSlsDetector::registerDataCallback(
int multiSlsDetector::setTotalProgress() { int multiSlsDetector::setTotalProgress() {
int nf = 1, nc = 1, ns = 1, nm = 1; int nf = 1, nc = 1, ns = 1, nm = 1;
if (thisMultiDetector->timerValue[FRAME_NUMBER]) { if (sharedMemory()->timerValue[FRAME_NUMBER]) {
nf = thisMultiDetector->timerValue[FRAME_NUMBER]; nf = sharedMemory()->timerValue[FRAME_NUMBER];
} }
if (thisMultiDetector->timerValue[CYCLES_NUMBER] > 0) { if (sharedMemory()->timerValue[CYCLES_NUMBER] > 0) {
nc = thisMultiDetector->timerValue[CYCLES_NUMBER]; nc = sharedMemory()->timerValue[CYCLES_NUMBER];
} }
if (thisMultiDetector->timerValue[STORAGE_CELL_NUMBER] > 0) { if (sharedMemory()->timerValue[STORAGE_CELL_NUMBER] > 0) {
ns = thisMultiDetector->timerValue[STORAGE_CELL_NUMBER] + 1; ns = sharedMemory()->timerValue[STORAGE_CELL_NUMBER] + 1;
} }
if (thisMultiDetector->timerValue[MEASUREMENTS_NUMBER] > 0) { if (sharedMemory()->timerValue[MEASUREMENTS_NUMBER] > 0) {
nm = thisMultiDetector->timerValue[MEASUREMENTS_NUMBER]; nm = sharedMemory()->timerValue[MEASUREMENTS_NUMBER];
} }
totalProgress = nm * nf * nc * ns; totalProgress = nm * nf * nc * ns;
@ -3967,10 +3924,10 @@ int multiSlsDetector::acquire() {
bool receiver = (setReceiverOnline() == ONLINE_FLAG); bool receiver = (setReceiverOnline() == ONLINE_FLAG);
progressIndex = 0; progressIndex = 0;
thisMultiDetector->stoppedFlag = 0; sharedMemory()->stoppedFlag = 0;
setJoinThreadFlag(false); setJoinThreadFlag(false);
int nm = thisMultiDetector->timerValue[MEASUREMENTS_NUMBER]; int nm = sharedMemory()->timerValue[MEASUREMENTS_NUMBER];
if (nm < 1) { if (nm < 1) {
nm = 1; nm = 1;
} }
@ -3980,7 +3937,7 @@ int multiSlsDetector::acquire() {
std::lock_guard<std::mutex> lock(mg); std::lock_guard<std::mutex> lock(mg);
if (getReceiverStatus() != IDLE) { if (getReceiverStatus() != IDLE) {
if (stopReceiver() == FAIL) { if (stopReceiver() == FAIL) {
thisMultiDetector->stoppedFlag = 1; sharedMemory()->stoppedFlag = 1;
} }
} }
} }
@ -3991,13 +3948,13 @@ int multiSlsDetector::acquire() {
if (receiver) { if (receiver) {
std::lock_guard<std::mutex> lock(mg); std::lock_guard<std::mutex> lock(mg);
if (resetFramesCaught() == FAIL) { if (resetFramesCaught() == FAIL) {
thisMultiDetector->stoppedFlag = 1; sharedMemory()->stoppedFlag = 1;
} }
} }
// loop through measurements // loop through measurements
for (int im = 0; im < nm; ++im) { for (int im = 0; im < nm; ++im) {
if (thisMultiDetector->stoppedFlag) { if (sharedMemory()->stoppedFlag) {
break; break;
} }
@ -4007,7 +3964,7 @@ int multiSlsDetector::acquire() {
if (startReceiver() == FAIL) { if (startReceiver() == FAIL) {
FILE_LOG(logERROR) << "Start receiver failed "; FILE_LOG(logERROR) << "Start receiver failed ";
stopReceiver(); stopReceiver();
thisMultiDetector->stoppedFlag = 1; sharedMemory()->stoppedFlag = 1;
break; break;
} }
// let processing thread listen to these packets // let processing thread listen to these packets
@ -4020,7 +3977,7 @@ int multiSlsDetector::acquire() {
std::lock_guard<std::mutex> lock(mg); std::lock_guard<std::mutex> lock(mg);
if (receiver) { if (receiver) {
if (stopReceiver() == FAIL) { if (stopReceiver() == FAIL) {
thisMultiDetector->stoppedFlag = 1; sharedMemory()->stoppedFlag = 1;
} else { } else {
if (dataReady) { if (dataReady) {
sem_wait(&sem_endRTAcquisition); // waits for receiver's sem_wait(&sem_endRTAcquisition); // waits for receiver's
@ -4035,7 +3992,7 @@ int multiSlsDetector::acquire() {
if (measurement_finished) { if (measurement_finished) {
measurement_finished(im, findex, measFinished_p); measurement_finished(im, findex, measFinished_p);
} }
if (thisMultiDetector->stoppedFlag) { if (sharedMemory()->stoppedFlag) {
break; break;
} }

View File

@ -7,12 +7,11 @@
* @short This is the base class for multi detector system functionalities * @short This is the base class for multi detector system functionalities
* @author Anna Bergamaschi * @author Anna Bergamaschi
*/ */
#include "SharedMemory.h"
#include "error_defs.h" #include "error_defs.h"
#include "logger.h" #include "logger.h"
#include "sls_detector_defs.h" #include "sls_detector_defs.h"
class slsDetector; class slsDetector;
class SharedMemory;
class ZmqSocket; class ZmqSocket;
class detectorData; class detectorData;
@ -27,15 +26,11 @@ class detectorData;
#define SHORT_STRING_LENGTH 50 #define SHORT_STRING_LENGTH 50
#define DATE_LENGTH 30 #define DATE_LENGTH 30
class multiSlsDetector : public virtual slsDetectorDefs, /**
public virtual errorDefs {
private:
/**
* @short structure allocated in shared memory to store detector settings * @short structure allocated in shared memory to store detector settings
* for IPC and cache * for IPC and cache
*/ */
typedef struct sharedMultiSlsDetector { struct sharedMultiSlsDetector {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND /* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND
* ------*/ * ------*/
@ -99,7 +94,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
int maxNumberOfChannelsPerDetector[2]; int maxNumberOfChannelsPerDetector[2];
/** timer values */ /** timer values */
int64_t timerValue[MAX_TIMERS]; int64_t timerValue[slsDetectorDefs::timerIndex::MAX_TIMERS];
/** flag for acquiring */ /** flag for acquiring */
bool acquiringFlag; bool acquiringFlag;
@ -110,8 +105,12 @@ class multiSlsDetector : public virtual slsDetectorDefs,
/** data streaming (up stream) enable in receiver */ /** data streaming (up stream) enable in receiver */
bool receiver_upstream; bool receiver_upstream;
};
} sharedMultiSlsDetector; class multiSlsDetector : public virtual slsDetectorDefs,
public virtual errorDefs {
// private:
public: public:
/** /**
@ -441,8 +440,6 @@ class multiSlsDetector : public virtual slsDetectorDefs,
*/ */
int setReceiverPort(int port_number = -1, int detPos = -1); int setReceiverPort(int port_number = -1, int detPos = -1);
/** /**
* Lock server for this client IP * Lock server for this client IP
* @param p 0 to unlock, 1 to lock * @param p 0 to unlock, 1 to lock
@ -471,7 +468,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int execCommand(const std::string& cmd, int detPos); int execCommand(const std::string &cmd, int detPos);
/** /**
* Load configuration from a configuration File * Load configuration from a configuration File
@ -542,7 +539,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns the trimbit/settings directory * @returns the trimbit/settings directory
*/ */
std::string setSettingsDir(const std::string& directory, int detPos = -1); std::string setSettingsDir(const std::string &directory, int detPos = -1);
/** /**
* Loads the modules settings/trimbits reading from a specific file * Loads the modules settings/trimbits reading from a specific file
@ -551,7 +548,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* returns OK or FAIL * returns OK or FAIL
*/ */
int loadSettingsFile(const std::string& fname, int detPos = -1); int loadSettingsFile(const std::string &fname, int detPos = -1);
/** /**
* Saves the modules settings/trimbits to a specific file * Saves the modules settings/trimbits to a specific file
@ -560,7 +557,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* returns OK or FAIL * returns OK or FAIL
*/ */
int saveSettingsFile(const std::string& fname, int detPos = -1); int saveSettingsFile(const std::string &fname, int detPos = -1);
/** /**
* Get Detector run status * Get Detector run status
@ -869,7 +866,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns the detector MAC address * @returns the detector MAC address
*/ */
std::string setDetectorMAC(const std::string& detectorMAC, int detPos = -1); std::string setDetectorMAC(const std::string &detectorMAC, int detPos = -1);
/** /**
* Returns the detector MAC address * Returns the detector MAC address
@ -884,7 +881,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns the detector IP address * @returns the detector IP address
*/ */
std::string setDetectorIP(const std::string& detectorIP, int detPos = -1); std::string setDetectorIP(const std::string &detectorIP, int detPos = -1);
/** /**
* Returns the detector IP address * Returns the detector IP address
@ -901,7 +898,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns the receiver IP address from shared memory * @returns the receiver IP address from shared memory
*/ */
std::string setReceiver(const std::string& receiver, int detPos = -1); std::string setReceiver(const std::string &receiver, int detPos = -1);
/** /**
* Returns the receiver IP address * Returns the receiver IP address
@ -916,7 +913,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns the receiver UDP IP address * @returns the receiver UDP IP address
*/ */
std::string setReceiverUDPIP(const std::string& udpip, int detPos = -1); std::string setReceiverUDPIP(const std::string &udpip, int detPos = -1);
/** /**
* Returns the receiver UDP IP address * Returns the receiver UDP IP address
@ -931,7 +928,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns the receiver UDP MAC address * @returns the receiver UDP MAC address
*/ */
std::string setReceiverUDPMAC(const std::string& udpmac, int detPos = -1); std::string setReceiverUDPMAC(const std::string &udpmac, int detPos = -1);
/** /**
* Returns the receiver UDP MAC address * Returns the receiver UDP MAC address
@ -948,7 +945,6 @@ class multiSlsDetector : public virtual slsDetectorDefs,
*/ */
int setReceiverUDPPort(int udpport, int detPos = -1); int setReceiverUDPPort(int udpport, int detPos = -1);
/** /**
* Returns the receiver UDP port * Returns the receiver UDP port
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
@ -1014,7 +1010,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* By default, it is the IP of receiver hostname * By default, it is the IP of receiver hostname
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
*/ */
void setClientDataStreamingInIP(const std::string& ip = "", void setClientDataStreamingInIP(const std::string &ip = "",
int detPos = -1); int detPos = -1);
/** /**
@ -1032,7 +1028,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* By default, it is the IP of receiver hostname * By default, it is the IP of receiver hostname
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
*/ */
void setReceiverDataStreamingOutIP(const std::string& ip = "", void setReceiverDataStreamingOutIP(const std::string &ip = "",
int detPos = -1); int detPos = -1);
/** /**
@ -1059,7 +1055,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns additional json header, default is empty * @returns additional json header, default is empty
*/ */
std::string setAdditionalJsonHeader(const std::string& jsonheader, int detPos = -1); std::string setAdditionalJsonHeader(const std::string &jsonheader, int detPos = -1);
/** /**
* Returns the additional json header * Returns the additional json header
@ -1076,7 +1072,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @returns the additional json header parameter value, * @returns the additional json header parameter value,
* empty if no parameter found in additional json header * empty if no parameter found in additional json header
*/ */
std::string setAdditionalJsonParameter(const std::string& key, const std::string& value, int detPos = -1); std::string setAdditionalJsonParameter(const std::string &key, const std::string &value, int detPos = -1);
/** /**
* Returns the additional json header parameter value * Returns the additional json header parameter value
@ -1085,7 +1081,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @returns the additional json header parameter value, * @returns the additional json header parameter value,
* empty if no parameter found in additional json header * empty if no parameter found in additional json header
*/ */
std::string getAdditionalJsonParameter(const std::string& key, int detPos = -1); std::string getAdditionalJsonParameter(const std::string &key, int detPos = -1);
/** /**
* Sets the detector minimum/maximum energy threshold in processor (for Moench only) * Sets the detector minimum/maximum energy threshold in processor (for Moench only)
@ -1117,14 +1113,14 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns receiver udp socket buffer size * @returns receiver udp socket buffer size
*/ */
uint64_t setReceiverUDPSocketBufferSize(uint64_t udpsockbufsize=-1, int detPos = -1); uint64_t setReceiverUDPSocketBufferSize(uint64_t udpsockbufsize = -1, int detPos = -1);
/** /**
* Returns the receiver UDP socket buffer size * Returns the receiver UDP socket buffer size
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns the receiver UDP socket buffer size * @returns the receiver UDP socket buffer size
*/ */
uint64_t getReceiverUDPSocketBufferSize(int detPos = -1) ; uint64_t getReceiverUDPSocketBufferSize(int detPos = -1);
/** /**
* Returns the receiver real UDP socket buffer size * Returns the receiver real UDP socket buffer size
@ -1360,7 +1356,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int programFPGA(const std::string& fname, int detPos = -1); int programFPGA(const std::string &fname, int detPos = -1);
/** /**
* Resets FPGA (Jungfrau) * Resets FPGA (Jungfrau)
@ -1461,7 +1457,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int execReceiverCommand(const std::string& cmd, int detPos = -1); int execReceiverCommand(const std::string &cmd, int detPos = -1);
/** /**
* Returns output file directory * Returns output file directory
@ -1476,7 +1472,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param s file directory * @param s file directory
* @returns file dir * @returns file dir
*/ */
std::string setFilePath(const std::string& path, int detPos = -1); std::string setFilePath(const std::string &path, int detPos = -1);
/** /**
* Returns file name prefix * Returns file name prefix
@ -1491,7 +1487,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param s file name prefix * @param s file name prefix
* @returns file name prefix * @returns file name prefix
*/ */
std::string setFileName(const std::string& fname, int detPos = -1); std::string setFileName(const std::string &fname, int detPos = -1);
/** /**
* Sets the max frames per file in receiver * Sets the max frames per file in receiver
@ -1693,7 +1689,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns OK/FAIL * @returns OK/FAIL
*/ */
int setPattern(const std::string& fname, int detPos = -1); int setPattern(const std::string &fname, int detPos = -1);
/** /**
* Writes a pattern word to the CTB * Writes a pattern word to the CTB
@ -1897,7 +1893,7 @@ class multiSlsDetector : public virtual slsDetectorDefs,
* Add sls detector * Add sls detector
* @param s hostname of the single detector * @param s hostname of the single detector
*/ */
void addSlsDetector(const std::string& hostname); void addSlsDetector(const std::string &hostname);
/** /**
* add gap pixels to the image (only for Eiger in 4 bit mode) * add gap pixels to the image (only for Eiger in 4 bit mode)
@ -1963,16 +1959,13 @@ class multiSlsDetector : public virtual slsDetectorDefs,
int detId; int detId;
/** Shared Memory object */ /** Shared Memory object */
SharedMemory *sharedMemory {nullptr}; SharedMemory<sharedMultiSlsDetector> sharedMemory{0, -1};
/** Shared memory structure */
sharedMultiSlsDetector *thisMultiDetector {nullptr};
/** pointers to the slsDetector structures */ /** pointers to the slsDetector structures */
std::vector<std::unique_ptr<slsDetector>> detectors; std::vector<std::unique_ptr<slsDetector>> detectors;
/** data streaming (down stream) enabled in client (zmq sckets created) */ /** data streaming (down stream) enabled in client (zmq sckets created) */
bool client_downstream {false}; bool client_downstream{false};
/** ZMQ Socket - Receiver to Client */ /** ZMQ Socket - Receiver to Client */
std::vector<std::unique_ptr<ZmqSocket>> zmqSocket; std::vector<std::unique_ptr<ZmqSocket>> zmqSocket;
@ -1986,10 +1979,10 @@ class multiSlsDetector : public virtual slsDetectorDefs,
sem_t sem_endRTAcquisition; sem_t sem_endRTAcquisition;
/** Total number of frames/images for next acquisition */ /** Total number of frames/images for next acquisition */
int totalProgress {0}; int totalProgress{0};
/** Current progress or frames/images processed in current acquisition */ /** Current progress or frames/images processed in current acquisition */
int progressIndex {0}; int progressIndex{0};
/** mutex to synchronize main and data processing threads */ /** mutex to synchronize main and data processing threads */
mutable std::mutex mp; mutable std::mutex mp;
@ -1998,26 +1991,26 @@ class multiSlsDetector : public virtual slsDetectorDefs,
mutable std::mutex mg; mutable std::mutex mg;
/** sets when the acquisition is finished */ /** sets when the acquisition is finished */
bool jointhread {false}; bool jointhread{false};
/** the data processing thread */ /** the data processing thread */
// pthread_t dataProcessingThread; // pthread_t dataProcessingThread;
std::thread dataProcessingThread; std::thread dataProcessingThread;
/** detector data packed for the gui */ /** detector data packed for the gui */
detectorData *thisData {nullptr}; detectorData *thisData{nullptr};
int (*acquisition_finished)(double, int, void *) {nullptr}; int (*acquisition_finished)(double, int, void *){nullptr};
void *acqFinished_p {nullptr}; void *acqFinished_p{nullptr};
int (*measurement_finished)(int, int, void *) {nullptr}; int (*measurement_finished)(int, int, void *){nullptr};
void *measFinished_p {nullptr}; void *measFinished_p{nullptr};
int (*progress_call)(double, void *); int (*progress_call)(double, void *);
void *pProgressCallArg {nullptr}; void *pProgressCallArg{nullptr};
int (*dataReady)(detectorData *, int, int, void *){nullptr}; int (*dataReady)(detectorData *, int, int, void *){nullptr};
void *pCallbackArg {nullptr}; void *pCallbackArg{nullptr};
}; };
#endif #endif

View File

@ -1,165 +0,0 @@
#include "SharedMemory.h"
#include "sls_detector_exceptions.h"
#include "ansi.h"
#include "logger.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>
#include "stdlib.h"
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
#define SHM_SLS_PREFIX "_sls_"
#define SHM_ENV_NAME "SLSDETNAME"
SharedMemory::SharedMemory(int multiId, int slsId):
fd(-1),
shmSize(0)
{
name = ConstructSharedMemoryName(multiId, slsId);
}
SharedMemory::~SharedMemory(){
if (fd >= 0)
close(fd);
}
bool SharedMemory::IsExisting() {
bool ret = true;
int tempfd = shm_open(name.c_str(), O_RDWR, 0);
if ((tempfd < 0) && (errno == ENOENT)) {
ret = false;
}
close(tempfd);
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) {
FILE_LOG(logERROR) << "Create shared memory " << name << " failed: " << strerror(errno);
throw SharedMemoryException();
}
// resize
if (ftruncate(fd, sz) < 0) {
FILE_LOG(logERROR) << "Create shared memory " << name << " failed at ftruncate: " << strerror(errno);
close(fd);
RemoveSharedMemory();
throw SharedMemoryException();
}
// map
void* addr = MapSharedMemory(sz);
FILE_LOG(logINFO) << "Shared memory created " << name;
return addr;
}
void* SharedMemory::OpenSharedMemory(size_t sz){
// open
fd = shm_open(name.c_str(), O_RDWR, 0);
if (fd < 0) {
FILE_LOG(logERROR) << "Open existing shared memory " << name << " failed: " << strerror(errno);
throw SharedMemoryException();
}
return MapSharedMemory(sz);
}
void SharedMemory::UnmapSharedMemory(void* addr) {
if (munmap(addr, shmSize) < 0) {
FILE_LOG(logERROR) << "Unmapping shared memory " << name << " failed: " << strerror(errno);
close(fd);
throw SharedMemoryException();
}
}
void SharedMemory::RemoveSharedMemory() {
if (shm_unlink(name.c_str()) < 0) {
// silent exit if shm did not exist anyway
if (errno == ENOENT)
return;
FILE_LOG(logERROR) << "Free Shared Memory " << name << " Failed: " << strerror(errno);
throw SharedMemoryException();
}
FILE_LOG(logINFO) << "Shared memory deleted " << name;
}
void* SharedMemory::MapSharedMemory(size_t sz) {
void* addr = mmap(nullptr, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
FILE_LOG(logERROR) << "Mapping shared memory " << name << " failed: " << strerror(errno);
close(fd);
throw SharedMemoryException();
}
shmSize = sz;
close(fd);
return addr;
}
std::string SharedMemory::ConstructSharedMemoryName(int multiId, int slsId) {
// using environment path
std::string sEnvPath = "";
char* envpath = getenv(SHM_ENV_NAME);
if (envpath != nullptr) {
sEnvPath.assign(envpath);
sEnvPath.insert(0,"_");
}
std::stringstream ss;
if (slsId < 0)
ss << SHM_MULTI_PREFIX << multiId << sEnvPath;
else
ss << SHM_MULTI_PREFIX << multiId << SHM_SLS_PREFIX << slsId << sEnvPath;
std::string temp = ss.str();
if (temp.length() > NAME_MAX) {
FILE_LOG(logERROR) << "Shared memory initialization failed. " <<
temp << " has " << temp.length() << " characters. \n"
"Maximum is " << NAME_MAX << ". Change the environment variable " << SHM_ENV_NAME;
throw SharedMemoryException();
}
return temp;
}
int SharedMemory::VerifySizeMatch(size_t expectedSize) {
struct stat sb;
// could not fstat
if (fstat(fd, &sb) < 0) {
FILE_LOG(logERROR) << "Could not verify existing shared memory " << name << " size match "
"(could not fstat): " << strerror(errno);
close(fd);
throw SharedMemoryException();
}
//size does not match
long unsigned int sz = (long unsigned int)sb.st_size;
if (sz != expectedSize) {
FILE_LOG(logERROR) << "Existing shared memory " << name << " size does not match";
FILE_LOG(logDEBUG1) << "Expected " << expectedSize << ", found " << sz;
throw SharedMemoryException();
return 1;
}
return 0;
}

View File

@ -8,68 +8,210 @@
*@short functions basic implemenation of shared memory *@short functions basic implemenation of shared memory
*/ */
#include "ansi.h"
#include "logger.h"
#include "sls_detector_exceptions.h"
#include "stdlib.h"
#include <cerrno> // errno
#include <cstring> // strerror
#include <fcntl.h> // O_CREAT, O_TRUNC..
#include <iostream>
#include <sstream>
#include <stdio.h> // printf
#include <sys/mman.h> // shared memory
#include <sys/stat.h> // fstat
#include <unistd.h>
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
#define SHM_SLS_PREFIX "_sls_"
#define SHM_ENV_NAME "SLSDETNAME"
#include <iostream> #include <iostream>
#include <string> #include <string>
class SharedMemory{ template <typename T>
public: class SharedMemory {
public:
/** /**
* Constructor * Constructor
* creates the single/multi detector shared memory name * creates the single/multi detector shared memory name
* @param multiId multi detector id * @param multiId multi detector id
* @param slsId sls detector id, -1 if a multi detector shared memory * @param slsId sls detector id, -1 if a multi detector shared memory
*/ */
SharedMemory(int multiId, int slsId); SharedMemory(int multiId, int slsId) {
name = ConstructSharedMemoryName(multiId, slsId);
}
/** /**
* Destructor * Delete the copy constructor and copy assignment since we don't want two
* objects managing the same resource
*/ */
~SharedMemory(); SharedMemory(const SharedMemory &) = delete;
SharedMemory &operator=(const SharedMemory &other) = delete;
//Move constructor
SharedMemory(SharedMemory &&other) : name(other.name),
fd(other.fd),
shmSize(other.shmSize),
shared_struct(other.shared_struct) {
other.fd = -1;
other.shared_struct = nullptr;
other.shmSize = 0;
}
//Move assignment
SharedMemory &operator=(SharedMemory &&other) {
name = other.name;
if (fd) {
close(fd);
}
fd = other.fd;
other.fd = -1;
if (shared_struct != nullptr) {
UnmapSharedMemory();
}
shared_struct = other.shared_struct;
other.shared_struct = nullptr;
shmSize = other.shmSize;
other.shmSize = 0;
return *this;
}
~SharedMemory() {
if (fd >= 0)
close(fd);
if (shared_struct) {
UnmapSharedMemory();
}
}
/** /**
* Verify if it exists * Verify if it exists
* @param name of shared memory * @param name of shared memory
* @return true if exists, else false * @return true if exists, else false
*/ */
bool IsExisting(); bool IsExisting() {
bool ret = true;
int tempfd = shm_open(name.c_str(), O_RDWR, 0);
if ((tempfd < 0) && (errno == ENOENT)) {
ret = false;
}
close(tempfd);
return ret;
}
/** /**
* Get shared memory name * Get shared memory name
*/ */
std::string GetName(); std::string GetName() const {
return name;
}
size_t size() const {
return shmSize;
}
/** /**
* Create Shared memory and call MapSharedMemory to map it to an address * Create Shared memory and call MapSharedMemory to map it to an address
* throws a SharedMemoryException exception on failure to create, ftruncate or map * throws a SharedMemoryException exception on failure to create, ftruncate or map
* @param sz of shared memory * @param sz of shared memory
*/ */
void* CreateSharedMemory(size_t sz); void CreateSharedMemory(size_t sz = 0) {
if (sz == 0) {
sz = sizeof(T);
}
fd = shm_open(name.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
FILE_LOG(logERROR) << "Create shared memory " << name << " failed: " << strerror(errno);
throw SharedMemoryException();
}
if (ftruncate(fd, sz) < 0) {
FILE_LOG(logERROR) << "Create shared memory " << name << " failed at ftruncate: " << strerror(errno);
close(fd);
RemoveSharedMemory();
throw SharedMemoryException();
}
shared_struct = MapSharedMemory(sz);
FILE_LOG(logINFO) << "Shared memory created " << name;
}
/** /**
* Open existing Shared memory and call MapSharedMemory to map it to an address * Open existing Shared memory and call MapSharedMemory to map it to an address
* throws a SharedMemoryException exception on failure to open or map * throws a SharedMemoryException exception on failure to open or map
* @param sz of shared memory * @param sz of shared memory
*/ */
void* OpenSharedMemory(size_t sz); void OpenSharedMemory(size_t sz = 0) {
if (sz == 0) {
sz = sizeof(T);
}
fd = shm_open(name.c_str(), O_RDWR, 0);
if (fd < 0) {
FILE_LOG(logERROR) << "Open existing shared memory " << name << " failed: " << strerror(errno);
throw SharedMemoryException();
}
shared_struct = MapSharedMemory(sz);
}
/** /**
* Unmap shared memory from an address * Unmap shared memory from an address
* throws a SharedMemoryException exception on failure * throws a SharedMemoryException exception on failure
* @param addr double pointer to address to be mapped
*/ */
void UnmapSharedMemory(void* addr); void UnmapSharedMemory() {
if (shared_struct != nullptr) {
if (munmap(shared_struct, shmSize) < 0) {
FILE_LOG(logERROR) << "Unmapping shared memory " << name << " failed: " << strerror(errno);
close(fd);
throw SharedMemoryException();
}
shared_struct = nullptr;
}
}
/** /**
* Remove existing Shared memory * Remove existing Shared memory
*/ */
void RemoveSharedMemory(); void RemoveSharedMemory() {
UnmapSharedMemory();
if (shm_unlink(name.c_str()) < 0) {
// silent exit if shm did not exist anyway
if (errno == ENOENT)
return;
FILE_LOG(logERROR) << "Free Shared Memory " << name << " Failed: " << strerror(errno);
throw SharedMemoryException();
}
FILE_LOG(logINFO) << "Shared memory deleted " << name;
}
/** /**
* Maximum length of name as from man pages * Maximum length of name as from man pages
*/ */
static const int NAME_MAX = 255; static const int NAME_MAX = 255;
private: /**
*Using the call operator to access the pointer
*/
T *operator()() {
return shared_struct;
}
/**
*Using the call operator to access the pointer, const overload
*/
const T *operator()() const {
return shared_struct;
}
private:
/** /**
* Create Shared memory name * Create Shared memory name
* throws exception if name created is longer than required 255(manpages) * throws exception if name created is longer than required 255(manpages)
@ -77,29 +219,85 @@ private:
* @param slsId sls detector id, -1 if a multi detector shared memory * @param slsId sls detector id, -1 if a multi detector shared memory
* @returns shared memory name * @returns shared memory name
*/ */
std::string ConstructSharedMemoryName(int multiId, int slsId); std::string ConstructSharedMemoryName(int multiId, int slsId) {
// using environment path
std::string sEnvPath = "";
char *envpath = getenv(SHM_ENV_NAME);
if (envpath != nullptr) {
sEnvPath.assign(envpath);
sEnvPath.insert(0, "_");
}
std::stringstream ss;
if (slsId < 0)
ss << SHM_MULTI_PREFIX << multiId << sEnvPath;
else
ss << SHM_MULTI_PREFIX << multiId << SHM_SLS_PREFIX << slsId << sEnvPath;
std::string temp = ss.str();
if (temp.length() > NAME_MAX) {
FILE_LOG(logERROR) << "Shared memory initialization failed. " << temp << " has " << temp.length() << " characters. \n"
"Maximum is "
<< NAME_MAX << ". Change the environment variable " << SHM_ENV_NAME;
throw SharedMemoryException();
}
return temp;
}
/** /**
* Map shared memory to an address * Map shared memory to an address
* throws a SharedMemoryException exception on failure * throws a SharedMemoryException exception on failure
* @param sz of shared memory * @param sz of shared memory
*/ */
void* MapSharedMemory(size_t sz);
T *MapSharedMemory(size_t sz) {
void *addr = mmap(nullptr, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
FILE_LOG(logERROR) << "Mapping shared memory " << name << " failed: " << strerror(errno);
close(fd);
throw SharedMemoryException();
}
shmSize = sz;
close(fd);
return (T *)addr;
}
/** /**
* Verify if existing shared memory size matches expected size * Verify if existing shared memory size matches expected size
* @param expectedSize expected size of shared memory, replaced with smaller size if size does not match * @param expectedSize expected size of shared memory, replaced with smaller size if size does not match
* @return 0 for success, 1 for fail * @return 0 for success, 1 for fail
*/ */
int VerifySizeMatch(size_t expectedSize); int VerifySizeMatch(size_t expectedSize) {
struct stat sb;
// could not fstat
if (fstat(fd, &sb) < 0) {
FILE_LOG(logERROR) << "Could not verify existing shared memory " << name << " size match "
"(could not fstat): "
<< strerror(errno);
close(fd);
throw SharedMemoryException();
}
//size does not match
long unsigned int sz = (long unsigned int)sb.st_size;
if (sz != expectedSize) {
FILE_LOG(logERROR) << "Existing shared memory " << name << " size does not match";
FILE_LOG(logDEBUG1) << "Expected " << expectedSize << ", found " << sz;
throw SharedMemoryException();
return 1;
}
return 0;
}
/** Shared memory name */ /** Shared memory name */
std::string name; std::string name;
/** File descriptor */ /** File descriptor */
int fd; int fd{-1};
/** shm size */ /** shm size */
size_t shmSize; size_t shmSize{0};
T *shared_struct{nullptr};
}; };

View File

@ -31,7 +31,7 @@ slsDetector::slsDetector(detectorType type, int multiId, int id, bool verify)
* so sls shared memory will be created */ * so sls shared memory will be created */
// ensure shared memory was not created before // ensure shared memory was not created before
auto shm = SharedMemory(multiId, id); SharedMemory<sharedSlsDetector> shm(multiId, id);
if (shm.IsExisting()) { if (shm.IsExisting()) {
FILE_LOG(logWARNING) << "This shared memory should have been " FILE_LOG(logWARNING) << "This shared memory should have been "
"deleted before! " "deleted before! "
@ -59,7 +59,7 @@ slsDetector::slsDetector(int multiId, int id, bool verify)
slsDetector::~slsDetector() { slsDetector::~slsDetector() {
if (sharedMemory) { if (sharedMemory) {
sharedMemory->UnmapSharedMemory(thisDetector); sharedMemory->UnmapSharedMemory();
delete sharedMemory; delete sharedMemory;
} }
} }
@ -202,13 +202,13 @@ int64_t slsDetector::getId(idMode mode) {
} }
void slsDetector::freeSharedMemory(int multiId, int slsId) { void slsDetector::freeSharedMemory(int multiId, int slsId) {
auto shm = SharedMemory(multiId, slsId); SharedMemory<sharedSlsDetector> shm(multiId, slsId);
shm.RemoveSharedMemory(); shm.RemoveSharedMemory();
} }
void slsDetector::freeSharedMemory() { void slsDetector::freeSharedMemory() {
if (sharedMemory) { if (sharedMemory) {
sharedMemory->UnmapSharedMemory(thisDetector); sharedMemory->UnmapSharedMemory();
sharedMemory->RemoveSharedMemory(); sharedMemory->RemoveSharedMemory();
delete sharedMemory; delete sharedMemory;
sharedMemory = nullptr; sharedMemory = nullptr;
@ -236,15 +236,17 @@ void slsDetector::initSharedMemory(bool created, detectorType type, int multiId,
int sz = calculateSharedMemorySize(type); int sz = calculateSharedMemorySize(type);
// shared memory object with name // shared memory object with name
sharedMemory = new SharedMemory(multiId, detId); sharedMemory = new SharedMemory<sharedSlsDetector>(multiId, detId);
// create // create
if (created) { if (created) {
thisDetector = (sharedSlsDetector *)sharedMemory->CreateSharedMemory(sz); sharedMemory->CreateSharedMemory(sz);
thisDetector = (*sharedMemory)();
} }
// open and verify version // open and verify version
else { else {
thisDetector = (sharedSlsDetector *)sharedMemory->OpenSharedMemory(sz); sharedMemory->OpenSharedMemory(sz);
thisDetector = (*sharedMemory)();
if (verify && thisDetector->shmversion != SLS_SHMVERSION) { if (verify && thisDetector->shmversion != SLS_SHMVERSION) {
FILE_LOG(logERROR) << "Single shared memory " FILE_LOG(logERROR) << "Single shared memory "
"(" "("
@ -259,7 +261,7 @@ void slsDetector::initSharedMemory(bool created, detectorType type, int multiId,
if (sharedMemory) { if (sharedMemory) {
// unmap // unmap
if (thisDetector) { if (thisDetector) {
sharedMemory->UnmapSharedMemory(thisDetector); sharedMemory->UnmapSharedMemory();
thisDetector = nullptr; thisDetector = nullptr;
} }
// delete // delete
@ -636,17 +638,16 @@ int slsDetector::receiveModule(sls_detector_module *myMod) {
} }
slsDetectorDefs::detectorType slsDetector::getDetectorTypeFromShm(int multiId, bool verify) { slsDetectorDefs::detectorType slsDetector::getDetectorTypeFromShm(int multiId, bool verify) {
auto shm = SharedMemory(multiId, detId); SharedMemory<sharedSlsDetector> shm(multiId, detId);
if (!shm.IsExisting()) { if (!shm.IsExisting()) {
FILE_LOG(logERROR) << "Shared memory " << shm.GetName() << " does not exist.\n" FILE_LOG(logERROR) << "Shared memory " << shm.GetName() << " does not exist.\n"
"Corrupted Multi Shared memory. Please free shared memory."; "Corrupted Multi Shared memory. Please free shared memory.";
throw SharedMemoryException(); throw SharedMemoryException();
} }
size_t sz = sizeof(sharedSlsDetector);
// open, map, verify version // open, map, verify version
auto sdet = (sharedSlsDetector *)shm.OpenSharedMemory(sz); shm.OpenSharedMemory();
auto sdet = shm();
if (verify && sdet->shmversion != SLS_SHMVERSION) { if (verify && sdet->shmversion != SLS_SHMVERSION) {
FILE_LOG(logERROR) << "Single shared memory " FILE_LOG(logERROR) << "Single shared memory "
"(" "("
@ -654,13 +655,13 @@ slsDetectorDefs::detectorType slsDetector::getDetectorTypeFromShm(int multiId, b
"(expected 0x" "(expected 0x"
<< std::hex << SLS_SHMVERSION << " but got 0x" << sdet->shmversion << ")" << std::dec; << std::hex << SLS_SHMVERSION << " but got 0x" << sdet->shmversion << ")" << std::dec;
// unmap and throw // unmap and throw
sharedMemory->UnmapSharedMemory(thisDetector); sharedMemory->UnmapSharedMemory();
throw SharedMemoryException(); throw SharedMemoryException();
} }
// get type, unmap // get type, unmap
auto type = sdet->myDetectorType; auto type = sdet->myDetectorType;
shm.UnmapSharedMemory(sdet); shm.UnmapSharedMemory();
return type; return type;
} }

View File

@ -9,17 +9,16 @@
* @author Anna Bergamaschi * @author Anna Bergamaschi
*/ */
#include "sls_detector_defs.h" #include "ClientSocket.h"
#include "SharedMemory.h"
#include "error_defs.h" #include "error_defs.h"
#include "logger.h" #include "logger.h"
#include "ClientSocket.h" #include "sls_detector_defs.h"
class ClientInterface; class ClientInterface;
#include <cmath> #include <cmath>
class multiSlsDetector; class multiSlsDetector;
class SharedMemory;
class ServerInterface; class ServerInterface;
class MySocketTCP; class MySocketTCP;
@ -41,14 +40,10 @@ typedef struct detParameterList {
int nGappixelsY; int nGappixelsY;
} detParameterList; } detParameterList;
/**
class slsDetector : public virtual slsDetectorDefs, public virtual errorDefs {
private:
/**
* @short structure allocated in shared memory to store detector settings for IPC and cache * @short structure allocated in shared memory to store detector settings for IPC and cache
*/ */
typedef struct sharedSlsDetector { struct sharedSlsDetector {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/ /* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
@ -68,13 +63,10 @@ private:
char hostname[MAX_STR_LENGTH]; char hostname[MAX_STR_LENGTH];
/** detector type \ see :: detectorType*/ /** detector type \ see :: detectorType*/
detectorType myDetectorType; slsDetectorDefs::detectorType myDetectorType;
/** END OF FIXED PATTERN -----------------------------------------------*/ /** END OF FIXED PATTERN -----------------------------------------------*/
/** Detector offset in the X & Y direction in the multi detector structure */ /** Detector offset in the X & Y direction in the multi detector structure */
int offset[2]; int offset[2];
@ -125,22 +117,22 @@ private:
int nROI; int nROI;
/** list of rois */ /** list of rois */
ROI roiLimits[MAX_ROIS]; slsDetectorDefs::ROI roiLimits[MAX_ROIS];
/** readout flags */ /** readout flags */
readOutFlags roFlags; slsDetectorDefs::readOutFlags roFlags;
/** name root of the output files */ /** name root of the output files */
char settingsFile[MAX_STR_LENGTH]; char settingsFile[MAX_STR_LENGTH];
/** detector settings (standard, fast, etc.) */ /** detector settings (standard, fast, etc.) */
detectorSettings currentSettings; slsDetectorDefs::detectorSettings currentSettings;
/** detector threshold (eV) */ /** detector threshold (eV) */
int currentThresholdEV; int currentThresholdEV;
/** timer values */ /** timer values */
int64_t timerValue[MAX_TIMERS]; int64_t timerValue[slsDetectorDefs::timerIndex::MAX_TIMERS];
/** memory offsets for the module structures */ /** memory offsets for the module structures */
int modoff; int modoff;
@ -226,7 +218,7 @@ private:
int64_t receiverAPIVersion; int64_t receiverAPIVersion;
/** receiver frames discard policy */ /** receiver frames discard policy */
frameDiscardPolicy receiver_frameDiscardMode; slsDetectorDefs::frameDiscardPolicy receiver_frameDiscardMode;
/** receiver partial frames padding enable */ /** receiver partial frames padding enable */
bool receiver_framePadding; bool receiver_framePadding;
@ -250,7 +242,7 @@ private:
int receiver_fileIndex; int receiver_fileIndex;
/** file format */ /** file format */
fileFormat receiver_fileFormatType; slsDetectorDefs::fileFormat receiver_fileFormatType;
/** frames per file */ /** frames per file */
int receiver_framesPerFile; int receiver_framesPerFile;
@ -260,15 +252,10 @@ private:
/** overwriteenable */ /** overwriteenable */
bool receiver_overWriteEnable; bool receiver_overWriteEnable;
};
} sharedSlsDetector; class slsDetector : public virtual slsDetectorDefs, public virtual errorDefs {
public:
public:
/** /**
* Constructor called when creating new shared memory * Constructor called when creating new shared memory
* @param type detector type * @param type detector type
@ -339,7 +326,7 @@ public:
* Sets the hostname, if online flag is set connects to update the detector * Sets the hostname, if online flag is set connects to update the detector
* @param name hostname * @param name hostname
*/ */
void setHostname(const std::string& hostname); void setHostname(const std::string &hostname);
/** /**
* Gets the hostname of detector * Gets the hostname of detector
@ -356,7 +343,7 @@ public:
* Get detector type by connecting to the detector * Get detector type by connecting to the detector
* @returns detector tpe or GENERIC if failed * @returns detector tpe or GENERIC if failed
*/ */
static detectorType getTypeFromDetector(const std::string& hostname, int cport=DEFAULT_PORTNO); static detectorType getTypeFromDetector(const std::string &hostname, int cport = DEFAULT_PORTNO);
/** /**
* Get Detector type from shared memory variable * Get Detector type from shared memory variable
@ -375,7 +362,7 @@ public:
* @param type the detector type * @param type the detector type
* @returns detector type in receiver * @returns detector type in receiver
*/ */
int setDetectorType(detectorType type=GET_DETECTOR_TYPE); int setDetectorType(detectorType type = GET_DETECTOR_TYPE);
/** /**
* Returns the total number of channels from shared memory * Returns the total number of channels from shared memory
@ -460,8 +447,7 @@ public:
* if ONLINE_FLAG, detector in online state (i.e. communication to the detector updating the local structure) * if ONLINE_FLAG, detector in online state (i.e. communication to the detector updating the local structure)
* @returns online/offline status * @returns online/offline status
*/ */
int setOnline(int value=GET_ONLINE_FLAG); int setOnline(int value = GET_ONLINE_FLAG);
/** /**
* Returns the online flag * Returns the online flag
@ -497,14 +483,14 @@ public:
* Returns the receiver TCP port \sa sharedSlsDetector * Returns the receiver TCP port \sa sharedSlsDetector
* @returns the receiver TCP port * @returns the receiver TCP port
*/ */
int getReceiverPort() const ; int getReceiverPort() const;
/** /**
* Lock server for this client IP * Lock server for this client IP
* @param p 0 to unlock, 1 to lock (-1 gets) * @param p 0 to unlock, 1 to lock (-1 gets)
* @returns 1 for locked or 0 for unlocked * @returns 1 for locked or 0 for unlocked
*/ */
int lockServer(int lock=-1); int lockServer(int lock = -1);
/** /**
* Get last client IP saved on detector server * Get last client IP saved on detector server
@ -524,13 +510,13 @@ public:
* @param cmd command to be executed * @param cmd command to be executed
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int execCommand(const std::string& cmd); int execCommand(const std::string &cmd);
/** /**
* Updates some of the shared memory receiving the data from the detector * Updates some of the shared memory receiving the data from the detector
* @returns OK * @returns OK
*/ */
int updateDetectorNoWait( sls::ClientSocket &client); int updateDetectorNoWait(sls::ClientSocket &client);
/** /**
* Updates some of the shared memory receiving the data from the detector * Updates some of the shared memory receiving the data from the detector
@ -546,7 +532,7 @@ public:
* @param m multiSlsDetector reference to parse commands * @param m multiSlsDetector reference to parse commands
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int writeConfigurationFile(const std::string& fname, multiSlsDetector* m); int writeConfigurationFile(const std::string &fname, multiSlsDetector *m);
/** /**
* Write current configuration to a stream * Write current configuration to a stream
@ -554,7 +540,7 @@ public:
* @param m multiSlsDetector reference to parse commands * @param m multiSlsDetector reference to parse commands
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int writeConfigurationFile(std::ofstream &outfile, multiSlsDetector* m); int writeConfigurationFile(std::ofstream &outfile, multiSlsDetector *m);
/** /**
* Returns the trimfile or settings file name (Useless??) * Returns the trimfile or settings file name (Useless??)
@ -569,7 +555,7 @@ public:
* @returns OK or FAIL if the file could not be written * @returns OK or FAIL if the file could not be written
* \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeSettingsFile(string, int) * \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeSettingsFile(string, int)
*/ */
int writeSettingsFile(const std::string& fname); int writeSettingsFile(const std::string &fname);
/** /**
* Get detector settings * Get detector settings
@ -602,7 +588,6 @@ public:
*/ */
int getThresholdEnergy(); int getThresholdEnergy();
/** /**
* Set threshold energy (Mythen and Eiger) * Set threshold energy (Mythen and Eiger)
* For Eiger, calls setThresholdEneryAndSettings * For Eiger, calls setThresholdEneryAndSettings
@ -611,7 +596,7 @@ public:
* @param tb 1 to include trimbits, 0 to exclude * @param tb 1 to include trimbits, 0 to exclude
* @returns current threshold value in ev (-1 failed) * @returns current threshold value in ev (-1 failed)
*/ */
int setThresholdEnergy(int e_eV, detectorSettings isettings=GET_SETTINGS, int tb=1); int setThresholdEnergy(int e_eV, detectorSettings isettings = GET_SETTINGS, int tb = 1);
/** /**
* Set threshold energy and settings (Eiger only) * Set threshold energy and settings (Eiger only)
@ -620,7 +605,7 @@ public:
* @param tb 1 to include trimbits, 0 to exclude * @param tb 1 to include trimbits, 0 to exclude
* @returns OK if successful, else FAIL * @returns OK if successful, else FAIL
*/ */
int setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, int tb=1); int setThresholdEnergyAndSettings(int e_eV, detectorSettings isettings, int tb = 1);
/** /**
* Returns the detector trimbit/settings directory \sa sharedSlsDetector * Returns the detector trimbit/settings directory \sa sharedSlsDetector
@ -633,7 +618,7 @@ public:
* @param s trimbits/settings directory * @param s trimbits/settings directory
* @returns the trimbit/settings directory * @returns the trimbit/settings directory
*/ */
std::string setSettingsDir(const std::string& dir); std::string setSettingsDir(const std::string &dir);
/** /**
* Loads the modules settings/trimbits reading from a specific file * Loads the modules settings/trimbits reading from a specific file
@ -641,7 +626,7 @@ public:
* @param fname specific settings/trimbits file * @param fname specific settings/trimbits file
* returns OK or FAIL * returns OK or FAIL
*/ */
int loadSettingsFile(const std::string& fname); int loadSettingsFile(const std::string &fname);
/** /**
* Saves the modules settings/trimbits to a specific file * Saves the modules settings/trimbits to a specific file
@ -649,7 +634,7 @@ public:
* @param fname specific settings/trimbits file * @param fname specific settings/trimbits file
* returns OK or FAIL * returns OK or FAIL
*/ */
int saveSettingsFile(const std::string& fname); int saveSettingsFile(const std::string &fname);
/** /**
* Get run status of the detector * Get run status of the detector
@ -711,7 +696,7 @@ public:
* @param t time in ns or number of...(e.g. frames, gates, probes) * @param t time in ns or number of...(e.g. frames, gates, probes)
* @returns timer set value in ns or number of...(e.g. frames, gates, probes) * @returns timer set value in ns or number of...(e.g. frames, gates, probes)
*/ */
int64_t setTimer(timerIndex index, int64_t t=-1); int64_t setTimer(timerIndex index, int64_t t = -1);
/** /**
* Set/get timer value left in acquisition (not all implemented for all detectors) * Set/get timer value left in acquisition (not all implemented for all detectors)
@ -727,7 +712,7 @@ public:
* @param value (clkdivider 0,1,2 for full, half and quarter speed). Other values check manual * @param value (clkdivider 0,1,2 for full, half and quarter speed). Other values check manual
* @returns value of speed set * @returns value of speed set
*/ */
int setSpeed(speedVariable sp, int value=-1); int setSpeed(speedVariable sp, int value = -1);
/** /**
* Set/get dynamic range and updates the number of dataBytes * Set/get dynamic range and updates the number of dataBytes
@ -736,7 +721,7 @@ public:
* @returns current dynamic range * @returns current dynamic range
* \sa sharedSlsDetector * \sa sharedSlsDetector
*/ */
int setDynamicRange(int n=-1); int setDynamicRange(int n = -1);
/** /**
* Recalculated number of data bytes * Recalculated number of data bytes
@ -771,7 +756,7 @@ public:
* @param pol timing mode (-1 gets) * @param pol timing mode (-1 gets)
* @returns current timing mode * @returns current timing mode
*/ */
externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol = GET_EXTERNAL_COMMUNICATION_MODE);
/** /**
* Set/get external signal flags (to specify triggerinrising edge etc) (Gotthard, Mythen) * Set/get external signal flags (to specify triggerinrising edge etc) (Gotthard, Mythen)
@ -779,14 +764,14 @@ public:
* @param signalindex singal index (0 - 3) * @param signalindex singal index (0 - 3)
* @returns current timing mode * @returns current timing mode
*/ */
externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); externalSignalFlag setExternalSignalFlags(externalSignalFlag pol = GET_EXTERNAL_SIGNAL_FLAG, int signalindex = 0);
/** /**
* Set/get readout flags (Eiger, Mythen) * Set/get readout flags (Eiger, Mythen)
* @param flag readout flag (Eiger options: parallel, nonparallel, safe etc.) (-1 gets) * @param flag readout flag (Eiger options: parallel, nonparallel, safe etc.) (-1 gets)
* @returns readout flag * @returns readout flag
*/ */
int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); int setReadOutFlags(readOutFlags flag = GET_READOUT_FLAGS);
/** /**
* Write in a register. For Advanced users * Write in a register. For Advanced users
@ -824,7 +809,7 @@ public:
* @param detectorMAC detector MAC address * @param detectorMAC detector MAC address
* @returns the detector MAC address * @returns the detector MAC address
*/ */
std::string setDetectorMAC(const std::string& detectorMAC); std::string setDetectorMAC(const std::string &detectorMAC);
/** /**
* Returns the detector MAC address\sa sharedSlsDetector * Returns the detector MAC address\sa sharedSlsDetector
@ -837,7 +822,7 @@ public:
* @param detectorIP detector IP address * @param detectorIP detector IP address
* @returns the detector IP address * @returns the detector IP address
*/ */
std::string setDetectorIP(const std::string& detectorIP); std::string setDetectorIP(const std::string &detectorIP);
/** /**
* Returns the detector IP address\sa sharedSlsDetector * Returns the detector IP address\sa sharedSlsDetector
@ -852,7 +837,7 @@ public:
* @param receiver receiver hostname or IP address * @param receiver receiver hostname or IP address
* @returns the receiver IP address from shared memory * @returns the receiver IP address from shared memory
*/ */
std::string setReceiver(const std::string& receiver); std::string setReceiver(const std::string &receiver);
/** /**
* Returns the receiver IP address\sa sharedSlsDetector * Returns the receiver IP address\sa sharedSlsDetector
@ -865,7 +850,7 @@ public:
* @param udpip receiver UDP IP address * @param udpip receiver UDP IP address
* @returns the receiver UDP IP address * @returns the receiver UDP IP address
*/ */
std::string setReceiverUDPIP(const std::string& udpip); std::string setReceiverUDPIP(const std::string &udpip);
/** /**
* Returns the receiver UDP IP address\sa sharedSlsDetector * Returns the receiver UDP IP address\sa sharedSlsDetector
@ -878,7 +863,7 @@ public:
* @param udpmac receiver UDP MAC address * @param udpmac receiver UDP MAC address
* @returns the receiver UDP MAC address * @returns the receiver UDP MAC address
*/ */
std::string setReceiverUDPMAC(const std::string& udpmac); std::string setReceiverUDPMAC(const std::string &udpmac);
/** /**
* Returns the receiver UDP MAC address\sa sharedSlsDetector * Returns the receiver UDP MAC address\sa sharedSlsDetector
@ -940,7 +925,7 @@ public:
* Sets the client zmq ip\sa sharedSlsDetector * Sets the client zmq ip\sa sharedSlsDetector
* @param sourceIP client zmq ip * @param sourceIP client zmq ip
*/ */
void setClientStreamingIP(const std::string& sourceIP); void setClientStreamingIP(const std::string &sourceIP);
/** /**
* Returns the client zmq ip \sa sharedSlsDetector * Returns the client zmq ip \sa sharedSlsDetector
@ -974,7 +959,7 @@ public:
* @param jsonheader additional json header * @param jsonheader additional json header
* @returns additional json header, returns "none" if default setting and no custom ip set * @returns additional json header, returns "none" if default setting and no custom ip set
*/ */
std::string setAdditionalJsonHeader(const std::string& jsonheader); std::string setAdditionalJsonHeader(const std::string &jsonheader);
/** /**
* Returns the additional json header \sa sharedSlsDetector * Returns the additional json header \sa sharedSlsDetector
@ -989,7 +974,7 @@ public:
* @returns the additional json header parameter value, * @returns the additional json header parameter value,
* empty if no parameter found in additional json header * empty if no parameter found in additional json header
*/ */
std::string setAdditionalJsonParameter(const std::string& key, const std::string& value); std::string setAdditionalJsonParameter(const std::string &key, const std::string &value);
/** /**
* Returns the additional json header parameter value * Returns the additional json header parameter value
@ -997,20 +982,20 @@ public:
* @returns the additional json header parameter value, * @returns the additional json header parameter value,
* empty if no parameter found in additional json header * empty if no parameter found in additional json header
*/ */
std::string getAdditionalJsonParameter(const std::string& key); std::string getAdditionalJsonParameter(const std::string &key);
/** /**
* Sets the receiver UDP socket buffer size * Sets the receiver UDP socket buffer size
* @param udpsockbufsize additional json header * @param udpsockbufsize additional json header
* @returns receiver udp socket buffer size * @returns receiver udp socket buffer size
*/ */
uint64_t setReceiverUDPSocketBufferSize(uint64_t udpsockbufsize=-1); uint64_t setReceiverUDPSocketBufferSize(uint64_t udpsockbufsize = -1);
/** /**
* Returns the receiver UDP socket buffer size\sa sharedSlsDetector * Returns the receiver UDP socket buffer size\sa sharedSlsDetector
* @returns the receiver UDP socket buffer size * @returns the receiver UDP socket buffer size
*/ */
uint64_t getReceiverUDPSocketBufferSize() ; uint64_t getReceiverUDPSocketBufferSize();
/** /**
* Returns the receiver real UDP socket buffer size\sa sharedSlsDetector * Returns the receiver real UDP socket buffer size\sa sharedSlsDetector
@ -1024,7 +1009,7 @@ public:
* @param value 1 to set or 0 to clear the digital test bit * @param value 1 to set or 0 to clear the digital test bit
* @returns result of test * @returns result of test
*/ */
int digitalTest(digitalTestMode mode, int ival=-1); int digitalTest(digitalTestMode mode, int ival = -1);
/** /**
* Load dark or gain image to detector (Gotthard) * Load dark or gain image to detector (Gotthard)
@ -1032,7 +1017,7 @@ public:
* @param fname file name from which to load image * @param fname file name from which to load image
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int loadImageToDetector(imageType index, const std::string& fname); int loadImageToDetector(imageType index, const std::string &fname);
/** /**
* Called from loadImageToDetector to send the image to detector * Called from loadImageToDetector to send the image to detector
@ -1048,7 +1033,7 @@ public:
* @param startACQ is 1 to start acquisition after reading counter * @param startACQ is 1 to start acquisition after reading counter
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int writeCounterBlockFile(const std::string& fname,int startACQ=0); int writeCounterBlockFile(const std::string &fname, int startACQ = 0);
/** /**
* Gets counter memory block in detector (Gotthard) * Gets counter memory block in detector (Gotthard)
@ -1056,14 +1041,14 @@ public:
* @param startACQ 1 to start acquisition afterwards, else 0 * @param startACQ 1 to start acquisition afterwards, else 0
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int getCounterBlock(int16_t image[],int startACQ=0); int getCounterBlock(int16_t image[], int startACQ = 0);
/** /**
* Resets counter in detector * Resets counter in detector
* @param startACQ is 1 to start acquisition after resetting counter * @param startACQ is 1 to start acquisition after resetting counter
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int resetCounterBlock(int startACQ=0); int resetCounterBlock(int startACQ = 0);
/** /**
* Set/get counter bit in detector (Gotthard) * Set/get counter bit in detector (Gotthard)
@ -1085,14 +1070,14 @@ public:
* @param roiLimits array of roi * @param roiLimits array of roi
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int setROI(int n=-1,ROI roiLimits[]=nullptr); int setROI(int n = -1, ROI roiLimits[] = nullptr);
/** /**
* Get ROI from each detector and convert it to the multi detector scale (Gotthard) * Get ROI from each detector and convert it to the multi detector scale (Gotthard)
* @param n number of rois * @param n number of rois
* @returns OK or FAIL * @returns OK or FAIL
*/ */
slsDetectorDefs::ROI* getROI(int &n); slsDetectorDefs::ROI *getROI(int &n);
/** /**
* Returns number of rois * Returns number of rois
@ -1107,7 +1092,7 @@ public:
* @param roiLimits ROI * @param roiLimits ROI
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int sendROI(int n=-1,ROI roiLimits[]=nullptr); int sendROI(int n = -1, ROI roiLimits[] = nullptr);
/** /**
* Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert users * Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert users
@ -1122,21 +1107,21 @@ public:
* @param enable active (1) or inactive (0), -1 gets * @param enable active (1) or inactive (0), -1 gets
* @returns 0 (inactive) or 1 (active)for activate mode * @returns 0 (inactive) or 1 (active)for activate mode
*/ */
int activate(int const enable=-1); int activate(int const enable = -1);
/** /**
* Set deactivated Receiver padding mode (Eiger only) * Set deactivated Receiver padding mode (Eiger only)
* @param padding padding option for deactivated receiver. Can be 1 (padding), 0 (no padding), -1 (gets) * @param padding padding option for deactivated receiver. Can be 1 (padding), 0 (no padding), -1 (gets)
* @returns 1 (padding), 0 (no padding), -1 (inconsistent values) for padding option * @returns 1 (padding), 0 (no padding), -1 (inconsistent values) for padding option
*/ */
int setDeactivatedRxrPaddingMode(int padding=-1); int setDeactivatedRxrPaddingMode(int padding = -1);
/** /**
* Returns the enable if data will be flipped across x or y axis (Eiger) * Returns the enable if data will be flipped across x or y axis (Eiger)
* @param d axis across which data is flipped * @param d axis across which data is flipped
* @returns 1 for flipped, else 0 * @returns 1 for flipped, else 0
*/ */
int getFlippedData(dimension d=X); int getFlippedData(dimension d = X);
/** /**
* Sets the enable which determines if * Sets the enable which determines if
@ -1145,7 +1130,7 @@ public:
* @param value 0 or 1 to reset/set or -1 to get value * @param value 0 or 1 to reset/set or -1 to get value
* @returns enable flipped data across x or y axis * @returns enable flipped data across x or y axis
*/ */
int setFlippedData(dimension d=X, int value=-1); int setFlippedData(dimension d = X, int value = -1);
/** /**
* Sets all the trimbits to a particular value (Eiger) * Sets all the trimbits to a particular value (Eiger)
@ -1160,7 +1145,7 @@ public:
* @param val 1 sets, 0 unsets, -1 gets * @param val 1 sets, 0 unsets, -1 gets
* @returns gap pixel enable or -1 for error * @returns gap pixel enable or -1 for error
*/ */
int enableGapPixels(int val=-1); int enableGapPixels(int val = -1);
/** /**
* Sets the number of trim energies and their value (Eiger) * Sets the number of trim energies and their value (Eiger)
@ -1169,7 +1154,7 @@ public:
* @param en array of energies * @param en array of energies
* @returns number of trim energies * @returns number of trim energies
*/ */
int setTrimEn(int nen, int *en=nullptr); int setTrimEn(int nen, int *en = nullptr);
/** /**
* Returns the number of trim energies and their value (Eiger) * Returns the number of trim energies and their value (Eiger)
@ -1177,7 +1162,7 @@ public:
* @param en array of energies * @param en array of energies
* @returns number of trim energies * @returns number of trim energies
*/ */
int getTrimEn(int *en=nullptr); int getTrimEn(int *en = nullptr);
/** /**
* Pulse Pixel (Eiger) * Pulse Pixel (Eiger)
@ -1186,7 +1171,7 @@ public:
* @param y is y coordinate * @param y is y coordinate
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int pulsePixel(int n=0,int x=0,int y=0); int pulsePixel(int n = 0, int x = 0, int y = 0);
/** /**
* Pulse Pixel and move by a relative value (Eiger) * Pulse Pixel and move by a relative value (Eiger)
@ -1195,49 +1180,49 @@ public:
* @param y is relative y value * @param y is relative y value
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int pulsePixelNMove(int n=0,int x=0,int y=0); int pulsePixelNMove(int n = 0, int x = 0, int y = 0);
/** /**
* Pulse Chip (Eiger) * Pulse Chip (Eiger)
* @param n is number of times to pulse * @param n is number of times to pulse
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int pulseChip(int n=0); int pulseChip(int n = 0);
/** /**
* Set/gets threshold temperature (Jungfrau) * Set/gets threshold temperature (Jungfrau)
* @param val value in millidegrees, -1 gets * @param val value in millidegrees, -1 gets
* @returns threshold temperature in millidegrees * @returns threshold temperature in millidegrees
*/ */
int setThresholdTemperature(int val=-1); int setThresholdTemperature(int val = -1);
/** /**
* Enables/disables temperature control (Jungfrau) * Enables/disables temperature control (Jungfrau)
* @param val value, -1 gets * @param val value, -1 gets
* @returns temperature control enable * @returns temperature control enable
*/ */
int setTemperatureControl(int val=-1); int setTemperatureControl(int val = -1);
/** /**
* Resets/ gets over-temperature event (Jungfrau) * Resets/ gets over-temperature event (Jungfrau)
* @param val value, -1 gets * @param val value, -1 gets
* @returns over-temperature event * @returns over-temperature event
*/ */
int setTemperatureEvent(int val=-1); int setTemperatureEvent(int val = -1);
/** /**
* Set storage cell that stores first acquisition of the series (Jungfrau) * Set storage cell that stores first acquisition of the series (Jungfrau)
* @param value storage cell index. Value can be 0 to 15. (-1 gets) * @param value storage cell index. Value can be 0 to 15. (-1 gets)
* @returns the storage cell that stores the first acquisition of the series * @returns the storage cell that stores the first acquisition of the series
*/ */
int setStoragecellStart(int pos=-1); int setStoragecellStart(int pos = -1);
/** /**
* Programs FPGA with pof file (Jungfrau) * Programs FPGA with pof file (Jungfrau)
* @param fname file name * @param fname file name
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int programFPGA(const std::string& fname); int programFPGA(const std::string &fname);
/** /**
* Resets FPGA (Jungfrau) * Resets FPGA (Jungfrau)
@ -1250,22 +1235,21 @@ public:
* @param ival on is 1, off is 0, -1 to get * @param ival on is 1, off is 0, -1 to get
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int powerChip(int ival= -1); int powerChip(int ival = -1);
/** /**
* Automatic comparator disable (Jungfrau) * Automatic comparator disable (Jungfrau)
* @param ival on is 1, off is 0, -1 to get * @param ival on is 1, off is 0, -1 to get
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int setAutoComparatorDisableMode(int ival= -1); int setAutoComparatorDisableMode(int ival = -1);
/** /**
* Returns the trimbits from the detector's shared memmory (Eiger) * Returns the trimbits from the detector's shared memmory (Eiger)
* @param retval is the array with the trimbits * @param retval is the array with the trimbits
* @returns total number of channels for the detector * @returns total number of channels for the detector
*/ */
int getChanRegs(double* retval); int getChanRegs(double *retval);
/** /**
* Configure Module (Eiger) * Configure Module (Eiger)
@ -1278,7 +1262,6 @@ public:
*/ */
int setModule(sls_detector_module module, int tb = 1); int setModule(sls_detector_module module, int tb = 1);
/** /**
* Get module structure from detector (all detectors) * Get module structure from detector (all detectors)
* @returns pointer to module structure (which has been created and must then be deleted) * @returns pointer to module structure (which has been created and must then be deleted)
@ -1312,7 +1295,7 @@ public:
* @param online 1 to set online, 0 to set offline, -1 gets * @param online 1 to set online, 0 to set offline, -1 gets
* @returns online, offline (from shared memory) * @returns online, offline (from shared memory)
*/ */
int setReceiverOnline(int value=GET_ONLINE_FLAG); int setReceiverOnline(int value = GET_ONLINE_FLAG);
int getReceiverOnline() const; int getReceiverOnline() const;
@ -1327,7 +1310,7 @@ public:
* @param lock sets (1), usets (0), gets (-1) the lock * @param lock sets (1), usets (0), gets (-1) the lock
* @returns lock status of the receiver * @returns lock status of the receiver
*/ */
int lockReceiver(int lock=-1); int lockReceiver(int lock = -1);
/** /**
* Returns the IP of the last client connecting to the receiver * Returns the IP of the last client connecting to the receiver
@ -1347,13 +1330,13 @@ public:
* @param cmd command to be executed * @param cmd command to be executed
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int execReceiverCommand(const std::string& cmd); int execReceiverCommand(const std::string &cmd);
/** /**
updates the shared memory receiving the data from the detector (without asking and closing the connection updates the shared memory receiving the data from the detector (without asking and closing the connection
/returns OK /returns OK
*/ */
int updateReceiverNoWait(sls::ClientSocket& receiver); int updateReceiverNoWait(sls::ClientSocket &receiver);
/** /**
* Updates the shared memory receiving the data from the detector * Updates the shared memory receiving the data from the detector
@ -1391,7 +1374,7 @@ public:
* @param s file directory * @param s file directory
* @returns file dir * @returns file dir
*/ */
std::string setFilePath(const std::string& path); std::string setFilePath(const std::string &path);
/** /**
* Returns file name prefix * Returns file name prefix
@ -1404,14 +1387,14 @@ public:
* @param s file name prefix * @param s file name prefix
* @returns file name prefix * @returns file name prefix
*/ */
std::string setFileName(const std::string& fname); std::string setFileName(const std::string &fname);
/** /**
* Sets the max frames per file in receiver * Sets the max frames per file in receiver
* @param f max frames per file * @param f max frames per file
* @returns max frames per file in receiver * @returns max frames per file in receiver
*/ */
int setReceiverFramesPerFile(int f=-1); int setReceiverFramesPerFile(int f = -1);
/** /**
* Sets the frames discard policy in receiver * Sets the frames discard policy in receiver
@ -1501,14 +1484,14 @@ public:
* @param enable 1 or 0 to set/reset file write enable * @param enable 1 or 0 to set/reset file write enable
* @returns file write enable * @returns file write enable
*/ */
int enableWriteToFile(int enable=-1); int enableWriteToFile(int enable = -1);
/** /**
* Sets/Gets file overwrite enable * Sets/Gets file overwrite enable
* @param enable 1 or 0 to set/reset file overwrite enable * @param enable 1 or 0 to set/reset file overwrite enable
* @returns file overwrite enable * @returns file overwrite enable
*/ */
int overwriteFile(int enable=-1); int overwriteFile(int enable = -1);
/** /**
* (previously setReadReceiverFrequency) * (previously setReadReceiverFrequency)
@ -1517,7 +1500,7 @@ public:
* @param detPos -1 for all detectors in list or specific detector position * @param detPos -1 for all detectors in list or specific detector position
* @returns receiver streaming frequency * @returns receiver streaming frequency
*/ */
int setReceiverStreamingFrequency(int freq=-1); int setReceiverStreamingFrequency(int freq = -1);
/** /**
* (previously setReceiverReadTimer) * (previously setReceiverReadTimer)
@ -1527,14 +1510,14 @@ public:
* @param time_in_ms timer between frames * @param time_in_ms timer between frames
* @returns receiver streaming timer in ms * @returns receiver streaming timer in ms
*/ */
int setReceiverStreamingTimer(int time_in_ms=500); int setReceiverStreamingTimer(int time_in_ms = 500);
/** /**
* Enable or disable streaming data from receiver to client * Enable or disable streaming data from receiver to client
* @param enable 0 to disable 1 to enable -1 to only get the value * @param enable 0 to disable 1 to enable -1 to only get the value
* @returns data streaming from receiver enable * @returns data streaming from receiver enable
*/ */
int enableDataStreamingFromReceiver(int enable=-1); int enableDataStreamingFromReceiver(int enable = -1);
/** /**
* Enable/disable or 10Gbe * Enable/disable or 10Gbe
@ -1571,7 +1554,7 @@ public:
* @param fname pattern file to open * @param fname pattern file to open
* @returns OK/FAIL * @returns OK/FAIL
*/ */
int setPattern(const std::string& fname); int setPattern(const std::string &fname);
/** /**
* Writes a pattern word to the CTB * Writes a pattern word to the CTB
@ -1579,7 +1562,7 @@ public:
* @param word 64bit word to be written, -1 gets * @param word 64bit word to be written, -1 gets
* @returns actual value * @returns actual value
*/ */
uint64_t setPatternWord(int addr,uint64_t word=-1); uint64_t setPatternWord(int addr, uint64_t word = -1);
/** /**
* Sets the pattern or loop limits in the CTB * Sets the pattern or loop limits in the CTB
@ -1589,7 +1572,7 @@ public:
* @param n number of loops (if level >=0) * @param n number of loops (if level >=0)
* @returns OK/FAIL * @returns OK/FAIL
*/ */
int setPatternLoops(int level,int &start, int &stop, int &n); int setPatternLoops(int level, int &start, int &stop, int &n);
/** /**
* Sets the wait address in the CTB * Sets the wait address in the CTB
@ -1597,7 +1580,7 @@ public:
* @param addr wait address, -1 gets * @param addr wait address, -1 gets
* @returns actual value * @returns actual value
*/ */
int setPatternWaitAddr(uint64_t level, uint64_t addr=-1); int setPatternWaitAddr(uint64_t level, uint64_t addr = -1);
/** /**
* Sets the wait time in the CTB * Sets the wait time in the CTB
@ -1605,7 +1588,7 @@ public:
* @param t wait time, -1 gets * @param t wait time, -1 gets
* @returns actual value * @returns actual value
*/ */
uint64_t setPatternWaitTime(uint64_t level, uint64_t t=-1); uint64_t setPatternWaitTime(uint64_t level, uint64_t t = -1);
/** /**
* Sets the mask applied to every pattern * Sets the mask applied to every pattern
@ -1648,8 +1631,7 @@ public:
*/ */
int setDigitalIODelay(uint64_t pinMask, int delay); int setDigitalIODelay(uint64_t pinMask, int delay);
private: private:
/** /**
* Get Detector Type from Shared Memory (opening shm without verifying size) * Get Detector Type from Shared Memory (opening shm without verifying size)
* @param multiId multi detector Id * @param multiId multi detector Id
@ -1673,7 +1655,7 @@ private:
* @param type detector type * @param type detector type
* @param list structure of parameters to initialize depending on detector type * @param list structure of parameters to initialize depending on detector type
*/ */
void setDetectorSpecificParameters(detectorType type, detParameterList& list); void setDetectorSpecificParameters(detectorType type, detParameterList &list);
/** /**
* Calculate shared memory size based on detector type * Calculate shared memory size based on detector type
@ -1708,7 +1690,7 @@ private:
* Uses current detector type * Uses current detector type
* @returns myMod the pointer to the allocate dmemory location * @returns myMod the pointer to the allocate dmemory location
*/ */
sls_detector_module* createModule(); sls_detector_module *createModule();
/** /**
* Allocates the memory for a sls_detector_module structure and initializes it * Allocates the memory for a sls_detector_module structure and initializes it
@ -1716,7 +1698,7 @@ private:
* @param type detector type * @param type detector type
* @returns myMod the pointer to the allocate dmemory location * @returns myMod the pointer to the allocate dmemory location
*/ */
sls_detector_module* createModule(detectorType type); sls_detector_module *createModule(detectorType type);
/** /**
* Frees the memory for a sls_detector_module structure * Frees the memory for a sls_detector_module structure
@ -1729,14 +1711,14 @@ private:
* @param myMod module structure to send * @param myMod module structure to send
* @returns number of bytes sent to the detector * @returns number of bytes sent to the detector
*/ */
int sendModule(sls_detector_module* myMod); int sendModule(sls_detector_module *myMod);
/** /**
* Receive a sls_detector_module structure over socket * Receive a sls_detector_module structure over socket
* @param myMod module structure to receive * @param myMod module structure to receive
* @returns number of bytes received from the detector * @returns number of bytes received from the detector
*/ */
int receiveModule(sls_detector_module* myMod); int receiveModule(sls_detector_module *myMod);
/** /**
* Get MAC from the receiver using udpip and * Get MAC from the receiver using udpip and
@ -1749,10 +1731,10 @@ private:
* Template function to do linear interpolation between two points (Eiger only) * Template function to do linear interpolation between two points (Eiger only)
*/ */
template <typename E, typename V> template <typename E, typename V>
V linearInterpolation(const E x, const E x1, const E x2, const V y1, const V y2){ V linearInterpolation(const E x, const E x1, const E x2, const V y1, const V y2) {
double k = static_cast<double>(y2-y1)/(x2-x1); double k = static_cast<double>(y2 - y1) / (x2 - x1);
double m = y1-k*x1; double m = y1 - k * x1;
int y = round( k*x+m ); int y = round(k * x + m);
return static_cast<V>(y); return static_cast<V>(y);
} }
@ -1766,9 +1748,9 @@ private:
* @param tb 1 to include trimbits, 0 to exclude (used for eiger) * @param tb 1 to include trimbits, 0 to exclude (used for eiger)
* @returns the pointer to the module structure with interpolated values or NULL if error * @returns the pointer to the module structure with interpolated values or NULL if error
*/ */
sls_detector_module* interpolateTrim( sls_detector_module *interpolateTrim(
sls_detector_module* a, sls_detector_module* b, const int energy, sls_detector_module *a, sls_detector_module *b, const int energy,
const int e1, const int e2, int tb=1); const int e1, const int e2, int tb = 1);
/** /**
* reads a trim/settings file * reads a trim/settings file
@ -1779,7 +1761,7 @@ private:
* @returns the pointer to myMod or NULL if reading the file failed * @returns the pointer to myMod or NULL if reading the file failed
*/ */
sls_detector_module* readSettingsFile(const std::string& fname, sls_detector_module* myMod=nullptr, int tb=1); sls_detector_module *readSettingsFile(const std::string &fname, sls_detector_module *myMod = nullptr, int tb = 1);
/** /**
* writes a trim/settings file * writes a trim/settings file
@ -1787,26 +1769,25 @@ private:
* @param mod module structure which has to be written to file * @param mod module structure which has to be written to file
* @returns OK or FAIL if the file could not be written * @returns OK or FAIL if the file could not be written
*/ */
int writeSettingsFile(const std::string& fname, sls_detector_module mod); int writeSettingsFile(const std::string &fname, sls_detector_module mod);
/** slsDetector Id or position in the detectors list */ /** slsDetector Id or position in the detectors list */
int detId; int detId;
/** Shared Memory object */ /** Shared Memory object */
SharedMemory* sharedMemory {nullptr}; SharedMemory<sharedSlsDetector> *sharedMemory{nullptr};
/** Shared memory structure */ /** Shared memory structure */
sharedSlsDetector *thisDetector {nullptr}; sharedSlsDetector *thisDetector{nullptr};
/** pointer to detector module structures in shared memory */ /** pointer to detector module structures in shared memory */
sls_detector_module *detectorModules {nullptr}; sls_detector_module *detectorModules{nullptr};
/** pointer to dac valuse in shared memory */ /** pointer to dac valuse in shared memory */
int *dacs {nullptr}; int *dacs{nullptr};
/** pointer to channel registers in shared memory */ /** pointer to channel registers in shared memory */
int *chanregs {nullptr}; int *chanregs{nullptr};
}; };
#endif #endif

View File

@ -0,0 +1,23 @@
include_directories(
${PROJECT_SOURCE_DIR}/catch
)
set(SOURCES
test.cpp
test-SharedMemory.cpp
)
add_executable(testSlsDetector ${SOURCES})
target_link_libraries(testSlsDetector
slsSupportLib
slsDetectorShared
pthread
rt
)
set_target_properties(testSlsDetector PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
#TODO! Move to automatic test discovery
add_test(test-testSlsDetector ${CMAKE_BINARY_DIR}/bin/testSlsDetector)

View File

@ -0,0 +1,128 @@
#include "SharedMemory.h"
#include "catch.hpp"
#include "string_utils.h"
#include <iostream>
struct Data {
int x;
double y;
char mess[50];
};
TEST_CASE("Create SharedMemory read and write") {
SharedMemory<Data> shm(0, -1);
shm.CreateSharedMemory();
CHECK(shm.GetName() == "/slsDetectorPackage_multi_0");
shm()->x = 3;
shm()->y = 5.7;
sls::strcpy_safe(shm()->mess, "Some string");
CHECK(shm()->x == 3);
CHECK(shm()->y == 5.7);
CHECK(std::string(shm()->mess) == "Some string");
shm.UnmapSharedMemory();
shm.RemoveSharedMemory();
CHECK(shm.IsExisting() == false);
}
TEST_CASE("Open existing SharedMemory and read") {
{
SharedMemory<double> shm(0, -1);
shm.CreateSharedMemory();
*shm() = 5.3;
}
SharedMemory<double> shm2(0, -1);
shm2.OpenSharedMemory();
CHECK(*shm2() == 5.3);
shm2.RemoveSharedMemory();
}
TEST_CASE("Creating a second shared memory with the same name throws") {
SharedMemory<double> shm0(0, -1);
SharedMemory<double> shm1(0, -1);
shm0.CreateSharedMemory();
CHECK_THROWS(shm1.CreateSharedMemory());
shm0.RemoveSharedMemory();
}
TEST_CASE("Open two shared memories to the same place") {
//Create the first shared memory
SharedMemory<Data> shm(0, -1);
shm.CreateSharedMemory();
shm()->x = 5;
CHECK(shm()->x == 5);
//Open the second shared memory with the same name
SharedMemory<Data> shm2(0, -1);
shm2.OpenSharedMemory();
CHECK(shm2()->x == 5);
CHECK(shm.GetName() == shm2.GetName());
//Check that they still point to the same place
shm2()->x = 7;
CHECK(shm()->x == 7);
//Remove only needs to be done once since they refer
//to the same memory
shm2.RemoveSharedMemory();
CHECK(shm.IsExisting() == false);
CHECK(shm2.IsExisting() == false);
}
TEST_CASE("Move SharedMemory"){
SharedMemory<Data> shm(0,-1);
CHECK(shm.GetName() == "/slsDetectorPackage_multi_0");
shm.CreateSharedMemory();
shm()->x = 9;
CHECK(shm.size()== sizeof(Data));
SharedMemory<Data> shm2(1,-1);
shm2 = std::move(shm); //shm is now a moved from object!
CHECK(shm2()->x == 9);
CHECK(shm() == nullptr);
CHECK(shm.size() == 0);
CHECK(shm2.GetName() == "/slsDetectorPackage_multi_0");
shm2.RemoveSharedMemory();
}
TEST_CASE("Create several shared memories") {
constexpr int N = 5;
std::vector<SharedMemory<int>> v;
v.reserve(N);
for (int i = 0; i != N; ++i) {
v.emplace_back(i, -1);
CHECK(v[i].IsExisting() == false);
v[i].CreateSharedMemory();
*v[i]() = i;
CHECK(*v[i]() == i);
}
for (int i = 0; i != N; ++i) {
CHECK(*v[i]() == i);
CHECK(v[i].GetName() == std::string("/slsDetectorPackage_multi_")+std::to_string(i));
}
for (int i = 0; i != N; ++i) {
v[i].RemoveSharedMemory();
CHECK(v[i].IsExisting() == false);
}
}

View File

@ -0,0 +1,3 @@
// tests-main.cpp
#define CATCH_CONFIG_MAIN
#include "catch.hpp"