diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index 0c551799e..e160c9700 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -31,12 +31,7 @@ multiSlsDetector::multiSlsDetector(int id, bool verify, bool update) setupMultiDetector(verify, update); } -multiSlsDetector::~multiSlsDetector() { - if (sharedMemory) { - sharedMemory->UnmapSharedMemory(); - delete sharedMemory; - } -} +multiSlsDetector::~multiSlsDetector() = default; void multiSlsDetector::setupMultiDetector(bool verify, bool update) { initSharedMemory(verify); @@ -197,21 +192,21 @@ void multiSlsDetector::setErrorMaskFromAllDetectors() { } void multiSlsDetector::setAcquiringFlag(bool b) { - thisMultiDetector->acquiringFlag = b; + sharedMemory()->acquiringFlag = b; } bool multiSlsDetector::getAcquiringFlag() const { - return thisMultiDetector->acquiringFlag; + return sharedMemory()->acquiringFlag; } bool multiSlsDetector::isAcquireReady() { - if (thisMultiDetector->acquiringFlag) { + if (sharedMemory()->acquiringFlag) { FILE_LOG(logWARNING) << "Acquire has already started. " "If previous acquisition terminated unexpectedly, " "reset busy flag to restart.(sls_detector_put busy 0)"; return FAIL; } - thisMultiDetector->acquiringFlag = true; + sharedMemory()->acquiringFlag = true; return OK; } @@ -250,23 +245,17 @@ void multiSlsDetector::freeSharedMemory(int multiId, int detPos) { } // multi - // get number of detectors + auto multiShm = SharedMemory(multiId, -1); int numDetectors = 0; - auto shm = SharedMemory(multiId, -1); - // get number of detectors from multi shm - if (shm.IsExisting()) { - // sharedMultiSlsDetector *mdet = - // (sharedMultiSlsDetector *)shm.OpenSharedMemory( - // sizeof(sharedMultiSlsDetector)); - shm.OpenSharedMemory(); - numDetectors = shm()->numberOfDetectors; - shm.UnmapSharedMemory(); - shm.RemoveSharedMemory(); + if (multiShm.IsExisting()) { + multiShm.OpenSharedMemory(); + numDetectors = multiShm()->numberOfDetectors; + multiShm.RemoveSharedMemory(); } for (int i = 0; i < numDetectors; ++i) { - auto shm = SharedMemory(multiId, i); + auto shm = SharedMemory(multiId, i); shm.RemoveSharedMemory(); } } @@ -287,17 +276,7 @@ void multiSlsDetector::freeSharedMemory(int detPos) { detectors.clear(); // clear multi detector shm - if (sharedMemory) { - if (thisMultiDetector) { - sharedMemory->UnmapSharedMemory(); - thisMultiDetector = nullptr; - } - sharedMemory->RemoveSharedMemory(); - delete sharedMemory; - sharedMemory = nullptr; - } - - // zmq + sharedMemory.RemoveSharedMemory(); //TODO verify use client_downstream = false; } @@ -313,82 +292,56 @@ std::string multiSlsDetector::getUserDetails() { sstream << d->getDetectorTypeAsString() << "+"; } - sstream << "\nPID: " << thisMultiDetector->lastPID - << "\nUser: " << thisMultiDetector->lastUser - << "\nDate: " << thisMultiDetector->lastDate << std::endl; + sstream << "\nPID: " << sharedMemory()->lastPID + << "\nUser: " << sharedMemory()->lastUser + << "\nDate: " << sharedMemory()->lastDate << std::endl; return sstream.str(); } /* - * pre: sharedMemory=0, thisMultiDetector = 0, detectors.size() = 0 - * exceptions are caught in calling function, shm unmapped and deleted + * pre: sharedMemory=0, sharedMemory() = 0, detectors.size() = 0 */ void multiSlsDetector::initSharedMemory(bool verify) { - try { - // shared memory object with name - sharedMemory = new SharedMemory(detId, -1); - // size_t sz = sizeof(sharedMultiSlsDetector); - - // create - if (!sharedMemory->IsExisting()) { - // thisMultiDetector = - // (sharedMultiSlsDetector *)sharedMemory->CreateSharedMemory(sz); - sharedMemory->CreateSharedMemory(); - thisMultiDetector= (*sharedMemory)(); //TODO remove line - initializeDetectorStructure(); + sharedMemory = SharedMemory(detId, -1); + if (!sharedMemory.IsExisting()) { + sharedMemory.CreateSharedMemory(); + initializeDetectorStructure(); + } + else { + sharedMemory.OpenSharedMemory(); + if (verify && sharedMemory()->shmversion != MULTI_SHMVERSION) { + FILE_LOG(logERROR) << "Multi shared memory (" << detId << ") version mismatch " + "(expected 0x" + << std::hex << MULTI_SHMVERSION << " but got 0x" << sharedMemory()->shmversion << std::dec; + throw SharedMemoryException(); } - // open and verify version - else { - // thisMultiDetector = - // (sharedMultiSlsDetector *)sharedMemory->OpenSharedMemory(sz); - sharedMemory->OpenSharedMemory(); - thisMultiDetector = (*sharedMemory)(); - if (verify && thisMultiDetector->shmversion != MULTI_SHMVERSION) { - FILE_LOG(logERROR) << "Multi shared memory (" << detId << ") version mismatch " - "(expected 0x" - << std::hex << MULTI_SHMVERSION << " but got 0x" << thisMultiDetector->shmversion << std::dec; - throw SharedMemoryException(); - } - } - } catch (...) { - if (sharedMemory) { - // unmap - if (thisMultiDetector) { - sharedMemory->UnmapSharedMemory(); - thisMultiDetector = nullptr; - } - // delete - delete sharedMemory; - sharedMemory = nullptr; - } - throw; } } void multiSlsDetector::initializeDetectorStructure() { - thisMultiDetector->shmversion = MULTI_SHMVERSION; - thisMultiDetector->numberOfDetectors = 0; - thisMultiDetector->numberOfDetector[X] = 0; - thisMultiDetector->numberOfDetector[Y] = 0; - thisMultiDetector->onlineFlag = 1; - thisMultiDetector->stoppedFlag = 0; - thisMultiDetector->dataBytes = 0; - thisMultiDetector->dataBytesInclGapPixels = 0; - thisMultiDetector->numberOfChannels = 0; - thisMultiDetector->numberOfChannel[X] = 0; - thisMultiDetector->numberOfChannel[Y] = 0; - thisMultiDetector->numberOfChannelInclGapPixels[X] = 0; - thisMultiDetector->numberOfChannelInclGapPixels[Y] = 0; - thisMultiDetector->maxNumberOfChannelsPerDetector[X] = 0; - thisMultiDetector->maxNumberOfChannelsPerDetector[Y] = 0; - for (int64_t &i : thisMultiDetector->timerValue) { + sharedMemory()->shmversion = MULTI_SHMVERSION; + sharedMemory()->numberOfDetectors = 0; + sharedMemory()->numberOfDetector[X] = 0; + sharedMemory()->numberOfDetector[Y] = 0; + sharedMemory()->onlineFlag = 1; + sharedMemory()->stoppedFlag = 0; + sharedMemory()->dataBytes = 0; + sharedMemory()->dataBytesInclGapPixels = 0; + sharedMemory()->numberOfChannels = 0; + sharedMemory()->numberOfChannel[X] = 0; + sharedMemory()->numberOfChannel[Y] = 0; + sharedMemory()->numberOfChannelInclGapPixels[X] = 0; + sharedMemory()->numberOfChannelInclGapPixels[Y] = 0; + sharedMemory()->maxNumberOfChannelsPerDetector[X] = 0; + sharedMemory()->maxNumberOfChannelsPerDetector[Y] = 0; + for (int64_t &i : sharedMemory()->timerValue) { i = 0; } - thisMultiDetector->acquiringFlag = false; - thisMultiDetector->receiverOnlineFlag = OFFLINE_FLAG; - thisMultiDetector->receiver_upstream = false; + sharedMemory()->acquiringFlag = false; + sharedMemory()->receiverOnlineFlag = OFFLINE_FLAG; + sharedMemory()->receiver_upstream = false; } void multiSlsDetector::initializeMembers(bool verify) { @@ -396,7 +349,7 @@ void multiSlsDetector::initializeMembers(bool verify) { zmqSocket.clear(); // 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 { detectors.push_back( sls::make_unique(detId, i, verify)); @@ -411,15 +364,15 @@ void multiSlsDetector::initializeMembers(bool verify) { } void multiSlsDetector::updateUserdetails() { - thisMultiDetector->lastPID = getpid(); - memset(thisMultiDetector->lastUser, 0, SHORT_STRING_LENGTH); - memset(thisMultiDetector->lastDate, 0, SHORT_STRING_LENGTH); + sharedMemory()->lastPID = getpid(); + memset(sharedMemory()->lastUser, 0, SHORT_STRING_LENGTH); + memset(sharedMemory()->lastDate, 0, SHORT_STRING_LENGTH); try { - sls::strcpy_safe(thisMultiDetector->lastUser, exec("whoami").c_str()); - sls::strcpy_safe(thisMultiDetector->lastDate, exec("date").c_str()); + sls::strcpy_safe(sharedMemory()->lastUser, exec("whoami").c_str()); + sls::strcpy_safe(sharedMemory()->lastDate, exec("date").c_str()); } catch (...) { - sls::strcpy_safe(thisMultiDetector->lastUser, "errorreading"); - sls::strcpy_safe(thisMultiDetector->lastDate, "errorreading"); + sls::strcpy_safe(sharedMemory()->lastUser, "errorreading"); + sls::strcpy_safe(sharedMemory()->lastDate, "errorreading"); } } @@ -455,7 +408,7 @@ void multiSlsDetector::setHostname(const char *name, int detPos) { // multi // 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." "Freeing Shared memory now."; freeSharedMemory(); @@ -508,11 +461,11 @@ void multiSlsDetector::addSlsDetector(const std::string &hostname) { int pos = (int)detectors.size(); detectors.push_back(sls::make_unique(type, detId, pos, false)); - thisMultiDetector->numberOfDetectors = detectors.size(); - thisMultiDetector->dataBytes += detectors[pos]->getDataBytes(); - thisMultiDetector->dataBytesInclGapPixels += + sharedMemory()->numberOfDetectors = detectors.size(); + sharedMemory()->dataBytes += detectors[pos]->getDataBytes(); + sharedMemory()->dataBytesInclGapPixels += detectors[pos]->getDataBytesInclGapPixels(); - thisMultiDetector->numberOfChannels += + sharedMemory()->numberOfChannels += detectors[pos]->getTotalNumberOfChannels(); detectors[pos]->setHostname(hostname); @@ -546,12 +499,12 @@ int multiSlsDetector::getNumberOfDetectors() const { } int multiSlsDetector::getNumberOfDetectors(dimension d) const { - return thisMultiDetector->numberOfDetector[d]; + return sharedMemory()->numberOfDetector[d]; } void multiSlsDetector::getNumberOfDetectors(int &nx, int &ny) const { - nx = thisMultiDetector->numberOfDetector[X]; - ny = thisMultiDetector->numberOfDetector[Y]; + nx = sharedMemory()->numberOfDetector[X]; + ny = sharedMemory()->numberOfDetector[Y]; } int multiSlsDetector::getTotalNumberOfChannels(int detPos) { @@ -561,7 +514,7 @@ int multiSlsDetector::getTotalNumberOfChannels(int detPos) { } // multi - return thisMultiDetector->numberOfChannels; + return sharedMemory()->numberOfChannels; } int multiSlsDetector::getTotalNumberOfChannels(dimension d, int detPos) { @@ -571,7 +524,7 @@ int multiSlsDetector::getTotalNumberOfChannels(dimension d, int detPos) { } // multi - return thisMultiDetector->numberOfChannel[d]; + return sharedMemory()->numberOfChannel[d]; } int multiSlsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d, @@ -582,16 +535,16 @@ int multiSlsDetector::getTotalNumberOfChannelsInclGapPixels(dimension d, } // multi - return thisMultiDetector->numberOfChannelInclGapPixels[d]; + return sharedMemory()->numberOfChannelInclGapPixels[d]; } int multiSlsDetector::getMaxNumberOfChannelsPerDetector(dimension d) { - return thisMultiDetector->maxNumberOfChannelsPerDetector[d]; + return sharedMemory()->maxNumberOfChannelsPerDetector[d]; } int multiSlsDetector::setMaxNumberOfChannelsPerDetector(dimension d, int i) { - thisMultiDetector->maxNumberOfChannelsPerDetector[d] = i; - return thisMultiDetector->maxNumberOfChannelsPerDetector[d]; + sharedMemory()->maxNumberOfChannelsPerDetector[d] = i; + return sharedMemory()->maxNumberOfChannelsPerDetector[d]; } int multiSlsDetector::getDetectorOffset(dimension d, int detPos) { @@ -606,22 +559,22 @@ void multiSlsDetector::updateOffsets() { FILE_LOG(logDEBUG1) << "Updating Multi-Detector Offsets"; int offsetX = 0, offsetY = 0, numX = 0, numY = 0; - int maxChanX = thisMultiDetector->maxNumberOfChannelsPerDetector[X]; - int maxChanY = thisMultiDetector->maxNumberOfChannelsPerDetector[Y]; + int maxChanX = sharedMemory()->maxNumberOfChannelsPerDetector[X]; + int maxChanY = sharedMemory()->maxNumberOfChannelsPerDetector[Y]; int prevChanX = 0; int prevChanY = 0; bool firstTime = true; - thisMultiDetector->numberOfChannel[X] = 0; - thisMultiDetector->numberOfChannel[Y] = 0; - thisMultiDetector->numberOfDetector[X] = 0; - thisMultiDetector->numberOfDetector[Y] = 0; + sharedMemory()->numberOfChannel[X] = 0; + sharedMemory()->numberOfChannel[Y] = 0; + sharedMemory()->numberOfDetector[X] = 0; + sharedMemory()->numberOfDetector[Y] = 0; // gap pixels int offsetX_gp = 0, offsetY_gp = 0, numX_gp = 0, numY_gp = 0; int prevChanX_gp = 0, prevChanY_gp = 0; - thisMultiDetector->numberOfChannelInclGapPixels[X] = 0; - thisMultiDetector->numberOfChannelInclGapPixels[Y] = 0; + sharedMemory()->numberOfChannelInclGapPixels[X] = 0; + sharedMemory()->numberOfChannelInclGapPixels[Y] = 0; 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; @@ -654,8 +607,8 @@ void multiSlsDetector::updateOffsets() { detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X); numY_gp += detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y); - ++thisMultiDetector->numberOfDetector[X]; - ++thisMultiDetector->numberOfDetector[Y]; + ++sharedMemory()->numberOfDetector[X]; + ++sharedMemory()->numberOfDetector[Y]; FILE_LOG(logDEBUG1) << "incrementing in both direction"; } @@ -673,8 +626,8 @@ void multiSlsDetector::updateOffsets() { numY_gp += detectors[idet]->getTotalNumberOfChannelsInclGapPixels(Y); // increment in y again only in the first column (else you double increment) - if (thisMultiDetector->numberOfDetector[X] == 1) - ++thisMultiDetector->numberOfDetector[Y]; + if (sharedMemory()->numberOfDetector[X] == 1) + ++sharedMemory()->numberOfDetector[Y]; FILE_LOG(logDEBUG1) << "incrementing in y direction"; } @@ -703,7 +656,7 @@ void multiSlsDetector::updateOffsets() { numX += detectors[idet]->getTotalNumberOfChannels(X); numX_gp += detectors[idet]->getTotalNumberOfChannelsInclGapPixels(X); - ++thisMultiDetector->numberOfDetector[X]; + ++sharedMemory()->numberOfDetector[X]; FILE_LOG(logDEBUG1) << "incrementing in x direction"; } @@ -721,28 +674,28 @@ void multiSlsDetector::updateOffsets() { << detectors[idet]->getDetectorOffset(Y) << ")"; // offsetY has been reset sometimes and offsetX the first time, // but remember the highest values - if (numX > thisMultiDetector->numberOfChannel[X]) { - thisMultiDetector->numberOfChannel[X] = numX; + if (numX > sharedMemory()->numberOfChannel[X]) { + sharedMemory()->numberOfChannel[X] = numX; } - if (numY > thisMultiDetector->numberOfChannel[Y]) { - thisMultiDetector->numberOfChannel[Y] = numY; + if (numY > sharedMemory()->numberOfChannel[Y]) { + sharedMemory()->numberOfChannel[Y] = numY; } - if (numX_gp > thisMultiDetector->numberOfChannelInclGapPixels[X]) { - thisMultiDetector->numberOfChannelInclGapPixels[X] = numX_gp; + if (numX_gp > sharedMemory()->numberOfChannelInclGapPixels[X]) { + sharedMemory()->numberOfChannelInclGapPixels[X] = numX_gp; } - if (numY_gp > thisMultiDetector->numberOfChannelInclGapPixels[Y]) { - thisMultiDetector->numberOfChannelInclGapPixels[Y] = numY_gp; + if (numY_gp > sharedMemory()->numberOfChannelInclGapPixels[Y]) { + 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 = - thisMultiDetector->numberOfChannel[0] * - thisMultiDetector->numberOfChannel[1]; + sharedMemory()->numberOfChannels = + sharedMemory()->numberOfChannel[0] * + sharedMemory()->numberOfChannel[1]; for (auto &d : detectors) { - d->updateMultiSize(thisMultiDetector->numberOfDetector[0], - thisMultiDetector->numberOfDetector[1]); + d->updateMultiSize(sharedMemory()->numberOfDetector[0], + sharedMemory()->numberOfDetector[1]); } } @@ -755,9 +708,9 @@ int multiSlsDetector::setOnline(int value, int detPos) { // multi if (value != GET_ONLINE_FLAG) { 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) { @@ -1109,12 +1062,12 @@ int multiSlsDetector::stopAcquisition(int detPos) { if (detPos >= 0) { // if only 1 detector, set flag to stop current acquisition if (detectors.size() == 1) { - thisMultiDetector->stoppedFlag = 1; + sharedMemory()->stoppedFlag = 1; } return detectors[detPos]->stopAcquisition(); } else { - thisMultiDetector->stoppedFlag = 1; + sharedMemory()->stoppedFlag = 1; auto r = parallelCall(&slsDetector::stopAcquisition); return sls::allEqualTo(r, static_cast(OK)) ? OK : FAIL; } @@ -1201,7 +1154,7 @@ int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t, int detPos) { << "Cannot set number of frames, cycles, " "storage cells or measurements individually."; setErrorMask(getErrorMask() | MUST_BE_MULTI_CMD); - return thisMultiDetector->timerValue[index]; + return sharedMemory()->timerValue[index]; default: break; } @@ -1232,7 +1185,7 @@ int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t, int detPos) { } } - thisMultiDetector->timerValue[index] = ret; + sharedMemory()->timerValue[index] = ret; return ret; } @@ -1400,16 +1353,16 @@ int multiSlsDetector::setDynamicRange(int dr, int detPos) { int ret = sls::minusOneIfDifferent(r); // update shm - int prevValue = thisMultiDetector->dataBytes; - int prevGValue = thisMultiDetector->dataBytesInclGapPixels; - thisMultiDetector->dataBytes = 0; - thisMultiDetector->dataBytesInclGapPixels = 0; - thisMultiDetector->numberOfChannels = 0; + int prevValue = sharedMemory()->dataBytes; + int prevGValue = sharedMemory()->dataBytesInclGapPixels; + sharedMemory()->dataBytes = 0; + sharedMemory()->dataBytesInclGapPixels = 0; + sharedMemory()->numberOfChannels = 0; for (auto &d : detectors) { - thisMultiDetector->dataBytes += d->getDataBytes(); - thisMultiDetector->dataBytesInclGapPixels += + sharedMemory()->dataBytes += d->getDataBytes(); + sharedMemory()->dataBytesInclGapPixels += d->getDataBytesInclGapPixels(); - thisMultiDetector->numberOfChannels += d->getTotalNumberOfChannels(); + sharedMemory()->numberOfChannels += d->getTotalNumberOfChannels(); } // for usability @@ -1432,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 // that instead - if ((prevValue != thisMultiDetector->dataBytes) || - (prevGValue != thisMultiDetector->dataBytesInclGapPixels)) { + if ((prevValue != sharedMemory()->dataBytes) || + (prevGValue != sharedMemory()->dataBytesInclGapPixels)) { updateOffsets(); } @@ -1960,7 +1913,6 @@ std::string multiSlsDetector::getAdditionalJsonParameter(const std::string &key, return sls::concatenateIfDifferent(r); } - int multiSlsDetector::setDetectorMinMaxEnergyThreshold(const int index, int value, int detPos) { std::string parameter = (index ? "emax" : "emin"); @@ -1976,7 +1928,7 @@ int multiSlsDetector::setDetectorMinMaxEnergyThreshold(const int index, int valu return stoi(result); } // not found or cannot scan integer - catch(...) { + catch (...) { return -1; } } @@ -2069,7 +2021,7 @@ int multiSlsDetector::loadImageToDetector(imageType index, // multi // read image for all - int nch = thisMultiDetector->numberOfChannels; + int nch = sharedMemory()->numberOfChannels; short int imageVals[nch]; if (readDataFile(fname, imageVals, nch) < nch * (int)sizeof(short int)) { FILE_LOG(logERROR) << "Could not open file or not enough data in file " @@ -2098,7 +2050,7 @@ int multiSlsDetector::writeCounterBlockFile(const std::string &fname, // multi // get image from all - int nch = thisMultiDetector->numberOfChannels; + int nch = sharedMemory()->numberOfChannels; short int imageVals[nch]; std::vector r; for (size_t idet = 0; idet < detectors.size(); ++idet) { @@ -2542,7 +2494,7 @@ int multiSlsDetector::enableGapPixels(int val, int detPos) { // update data bytes incl gap pixels if (val != -1) { auto r = serialCall(&slsDetector::getDataBytesInclGapPixels); - thisMultiDetector->dataBytesInclGapPixels = sls::sum(r); + sharedMemory()->dataBytesInclGapPixels = sls::sum(r); // update updateOffsets(); @@ -2749,9 +2701,9 @@ int multiSlsDetector::setReceiverOnline(int value, int detPos) { // multi if (value != GET_ONLINE_FLAG) { 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) { @@ -3089,8 +3041,8 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) { void multiSlsDetector::readFrameFromReceiver() { int nX = - thisMultiDetector->numberOfDetector[X]; // to copy data in multi module - int nY = thisMultiDetector + sharedMemory()->numberOfDetector[X]; // to copy data in multi module + int nY = sharedMemory() ->numberOfDetector[Y]; // for eiger, to reverse the data bool gappixelsenable = false; bool eiger = false; @@ -3238,8 +3190,8 @@ void multiSlsDetector::readFrameFromReceiver() { // 4bit gap pixels if (dynamicRange == 4 && gappixelsenable) { int n = processImageWithGapPixels(multiframe, multigappixels); - nPixelsX = thisMultiDetector->numberOfChannelInclGapPixels[X]; - nPixelsY = thisMultiDetector->numberOfChannelInclGapPixels[Y]; + nPixelsX = sharedMemory()->numberOfChannelInclGapPixels[X]; + nPixelsY = sharedMemory()->numberOfChannelInclGapPixels[Y]; thisData = new detectorData(getCurrentProgress(), currentFileName.c_str(), nPixelsX, nPixelsY, multigappixels, n, @@ -3295,12 +3247,12 @@ void multiSlsDetector::readFrameFromReceiver() { int multiSlsDetector::processImageWithGapPixels(char *image, char *&gpImage) { // eiger 4 bit mode - int nxb = thisMultiDetector->numberOfDetector[X] * (512 + 3); - int nyb = thisMultiDetector->numberOfDetector[Y] * (256 + 1); + int nxb = sharedMemory()->numberOfDetector[X] * (512 + 3); + int nyb = sharedMemory()->numberOfDetector[Y] * (256 + 1); int gapdatabytes = nxb * nyb; - int nxchip = thisMultiDetector->numberOfDetector[X] * 4; - int nychip = thisMultiDetector->numberOfDetector[Y] * 1; + int nxchip = sharedMemory()->numberOfDetector[X] * 4; + int nychip = sharedMemory()->numberOfDetector[Y] * 1; // allocate if (gpImage == nullptr) { @@ -3564,7 +3516,7 @@ uint64_t multiSlsDetector::setPatternWord(int addr, uint64_t word, int detPos) { } int multiSlsDetector::setPatternLoops(int level, int &start, int &stop, int &n, - int detPos) { + int detPos) { // single if (detPos >= 0) { return detectors[detPos]->setPatternLoops(level, start, stop, n); @@ -3907,20 +3859,20 @@ void multiSlsDetector::registerDataCallback( int multiSlsDetector::setTotalProgress() { int nf = 1, nc = 1, ns = 1, nm = 1; - if (thisMultiDetector->timerValue[FRAME_NUMBER]) { - nf = thisMultiDetector->timerValue[FRAME_NUMBER]; + if (sharedMemory()->timerValue[FRAME_NUMBER]) { + nf = sharedMemory()->timerValue[FRAME_NUMBER]; } - if (thisMultiDetector->timerValue[CYCLES_NUMBER] > 0) { - nc = thisMultiDetector->timerValue[CYCLES_NUMBER]; + if (sharedMemory()->timerValue[CYCLES_NUMBER] > 0) { + nc = sharedMemory()->timerValue[CYCLES_NUMBER]; } - if (thisMultiDetector->timerValue[STORAGE_CELL_NUMBER] > 0) { - ns = thisMultiDetector->timerValue[STORAGE_CELL_NUMBER] + 1; + if (sharedMemory()->timerValue[STORAGE_CELL_NUMBER] > 0) { + ns = sharedMemory()->timerValue[STORAGE_CELL_NUMBER] + 1; } - if (thisMultiDetector->timerValue[MEASUREMENTS_NUMBER] > 0) { - nm = thisMultiDetector->timerValue[MEASUREMENTS_NUMBER]; + if (sharedMemory()->timerValue[MEASUREMENTS_NUMBER] > 0) { + nm = sharedMemory()->timerValue[MEASUREMENTS_NUMBER]; } totalProgress = nm * nf * nc * ns; @@ -3972,10 +3924,10 @@ int multiSlsDetector::acquire() { bool receiver = (setReceiverOnline() == ONLINE_FLAG); progressIndex = 0; - thisMultiDetector->stoppedFlag = 0; + sharedMemory()->stoppedFlag = 0; setJoinThreadFlag(false); - int nm = thisMultiDetector->timerValue[MEASUREMENTS_NUMBER]; + int nm = sharedMemory()->timerValue[MEASUREMENTS_NUMBER]; if (nm < 1) { nm = 1; } @@ -3985,7 +3937,7 @@ int multiSlsDetector::acquire() { std::lock_guard lock(mg); if (getReceiverStatus() != IDLE) { if (stopReceiver() == FAIL) { - thisMultiDetector->stoppedFlag = 1; + sharedMemory()->stoppedFlag = 1; } } } @@ -3996,13 +3948,13 @@ int multiSlsDetector::acquire() { if (receiver) { std::lock_guard lock(mg); if (resetFramesCaught() == FAIL) { - thisMultiDetector->stoppedFlag = 1; + sharedMemory()->stoppedFlag = 1; } } // loop through measurements for (int im = 0; im < nm; ++im) { - if (thisMultiDetector->stoppedFlag) { + if (sharedMemory()->stoppedFlag) { break; } @@ -4012,7 +3964,7 @@ int multiSlsDetector::acquire() { if (startReceiver() == FAIL) { FILE_LOG(logERROR) << "Start receiver failed "; stopReceiver(); - thisMultiDetector->stoppedFlag = 1; + sharedMemory()->stoppedFlag = 1; break; } // let processing thread listen to these packets @@ -4025,7 +3977,7 @@ int multiSlsDetector::acquire() { std::lock_guard lock(mg); if (receiver) { if (stopReceiver() == FAIL) { - thisMultiDetector->stoppedFlag = 1; + sharedMemory()->stoppedFlag = 1; } else { if (dataReady) { sem_wait(&sem_endRTAcquisition); // waits for receiver's @@ -4040,7 +3992,7 @@ int multiSlsDetector::acquire() { if (measurement_finished) { measurement_finished(im, findex, measFinished_p); } - if (thisMultiDetector->stoppedFlag) { + if (sharedMemory()->stoppedFlag) { break; } diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h index 3a80bc2f2..21d6b0dd9 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h @@ -1966,7 +1966,7 @@ class multiSlsDetector : public virtual slsDetectorDefs, int detId; /** Shared Memory object */ - SharedMemory *sharedMemory {nullptr}; + SharedMemory sharedMemory{0,-1}; /** Shared memory structure */ sharedMultiSlsDetector *thisMultiDetector {nullptr}; diff --git a/slsDetectorSoftware/sharedMemory/SharedMemory.h b/slsDetectorSoftware/sharedMemory/SharedMemory.h index 19782263e..a5c9d68f5 100644 --- a/slsDetectorSoftware/sharedMemory/SharedMemory.h +++ b/slsDetectorSoftware/sharedMemory/SharedMemory.h @@ -39,8 +39,7 @@ class SharedMemory { * @param multiId multi detector id * @param slsId sls detector id, -1 if a multi detector shared memory */ - SharedMemory(int multiId, int slsId) : fd(-1), - shmSize(0) { + SharedMemory(int multiId, int slsId){ name = ConstructSharedMemoryName(multiId, slsId); } @@ -50,6 +49,10 @@ class SharedMemory { ~SharedMemory() { if (fd >= 0) close(fd); + + if (shared_struct) { + UnmapSharedMemory(); + } } /** @@ -81,10 +84,10 @@ class SharedMemory { */ void CreateSharedMemory(size_t sz = 0) { // create - if (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); @@ -112,9 +115,12 @@ class SharedMemory { * throws a SharedMemoryException exception on failure to open or map * @param sz of shared memory */ - void OpenSharedMemory() { + void OpenSharedMemory(size_t sz = 0) { // open - size_t sz = sizeof(T); + 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); @@ -130,10 +136,13 @@ class SharedMemory { * throws a SharedMemoryException exception on failure */ void UnmapSharedMemory() { - if (munmap(shared_struct, shmSize) < 0) { - FILE_LOG(logERROR) << "Unmapping shared memory " << name << " failed: " << strerror(errno); - close(fd); - throw SharedMemoryException(); + 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; } } @@ -141,6 +150,7 @@ class SharedMemory { * Remove existing Shared memory */ void RemoveSharedMemory() { + UnmapSharedMemory(); if (shm_unlink(name.c_str()) < 0) { // silent exit if shm did not exist anyway if (errno == ENOENT) @@ -252,10 +262,10 @@ class SharedMemory { std::string name; /** File descriptor */ - int fd; + int fd{-1}; /** shm size */ - size_t shmSize; + size_t shmSize{0}; - T *shared_struct; + T *shared_struct{nullptr}; }; diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index d0c039c87..e3291fa52 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -247,7 +247,7 @@ void slsDetector::initSharedMemory(bool created, detectorType type, int multiId, // open and verify version else { // thisDetector = (sharedSlsDetector *)sharedMemory->OpenSharedMemory(sz); - sharedMemory->OpenSharedMemory(); + sharedMemory->OpenSharedMemory(sz); thisDetector = (*sharedMemory)(); if (verify && thisDetector->shmversion != SLS_SHMVERSION) { FILE_LOG(logERROR) << "Single shared memory " diff --git a/slsDetectorSoftware/tests/test-SharedMemory.cpp b/slsDetectorSoftware/tests/test-SharedMemory.cpp index e541ad3e2..8231070a9 100644 --- a/slsDetectorSoftware/tests/test-SharedMemory.cpp +++ b/slsDetectorSoftware/tests/test-SharedMemory.cpp @@ -1,18 +1,17 @@ -#include "catch.hpp" #include "SharedMemory.h" +#include "catch.hpp" #include "string_utils.h" +struct Data { + int x; + double y; + char mess[50]; +}; -TEST_CASE("SharedMemory") { - struct Data{ - int x; - double y; - char mess[50]; - }; +TEST_CASE("Create SharedMemory read and write") { - - SharedMemory shm(0,-1); + SharedMemory shm(0, -1); shm.CreateSharedMemory(); CHECK(shm.GetName() == "/slsDetectorPackage_multi_0"); @@ -26,5 +25,54 @@ TEST_CASE("SharedMemory") { shm.UnmapSharedMemory(); shm.RemoveSharedMemory(); +} +TEST_CASE("Open existing SharedMemory and read") { + + SharedMemory shm(0, -1); + shm.CreateSharedMemory(); + *shm() = 5.3; + shm.UnmapSharedMemory(); + + SharedMemory shm2(0, -1); + shm2.OpenSharedMemory(); + CHECK(*shm2() == 5.3); + + shm2.RemoveSharedMemory(); +} + +TEST_CASE("Two shared memories with the same name throws") { + + SharedMemory shm0(0, -1); + SharedMemory 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 shm(0, -1); + shm.CreateSharedMemory(); + shm()->x = 5; + CHECK(shm()->x == 5); + + //Open the second shared memory with the same name + SharedMemory 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); } \ No newline at end of file