Dev/verify shm (#1276)
Some checks failed
Build on RHEL9 / build (push) Failing after 3m41s
Build on RHEL8 / build (push) Failing after 5m10s

* removed verify, update, fixed getUser to be a free function, generated commands, python bindings yet to do

* python bindings

* fixed tests

* minor

* minor

* format
This commit is contained in:
2025-08-23 10:23:27 +02:00
committed by GitHub
parent 15cbaa509e
commit fff5fa73be
18 changed files with 198 additions and 209 deletions

View File

@@ -15,7 +15,7 @@ from .gaincaps import Mythen3GainCapsWrapper
from .PatternGenerator import PatternGenerator from .PatternGenerator import PatternGenerator
from . import _slsdet from . import _slsdet
from ._slsdet import freeSharedMemory from ._slsdet import freeSharedMemory, getUserDetails
xy = _slsdet.xy xy = _slsdet.xy
defs = _slsdet.slsDetectorDefs defs = _slsdet.slsDetectorDefs

View File

@@ -15,7 +15,7 @@ defs = slsDetectorDefs
from .utils import element_if_equal, all_equal, get_set_bits, list_to_bitmask from .utils import element_if_equal, all_equal, get_set_bits, list_to_bitmask
from .utils import Geometry, to_geo, element, reduce_time, is_iterable, hostname_list from .utils import Geometry, to_geo, element, reduce_time, is_iterable, hostname_list
from ._slsdet import xy, freeSharedMemory from ._slsdet import xy, freeSharedMemory, getUserDetails
from .gaincaps import Mythen3GainCapsWrapper from .gaincaps import Mythen3GainCapsWrapper
from . import utils as ut from . import utils as ut
from .proxy import JsonProxy, SlowAdcProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy from .proxy import JsonProxy, SlowAdcProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy
@@ -1537,7 +1537,7 @@ class Detector(CppDetectorApi):
""" """
Retrieve user details from shared memory (hostname, type, PID, User, Date) Retrieve user details from shared memory (hostname, type, PID, User, Date)
""" """
return self.getUserDetails() return getUserDetails(self.getShmId())
@property @property
@element @element

View File

@@ -25,6 +25,9 @@ void init_det(py::module &m) {
(void (*)(const int, const int)) & sls::freeSharedMemory, (void (*)(const int, const int)) & sls::freeSharedMemory,
py::arg() = 0, py::arg() = -1); py::arg() = 0, py::arg() = -1);
m.def("getUserDetails", (std::string(*)(const int)) & sls::getUserDetails,
py::arg() = 0);
py::class_<Detector> CppDetectorApi(m, "CppDetectorApi"); py::class_<Detector> CppDetectorApi(m, "CppDetectorApi");
CppDetectorApi.def(py::init<int>()); CppDetectorApi.def(py::init<int>());
@@ -2063,7 +2066,5 @@ void init_det(py::module &m) {
(Result<sls::ns>(Detector::*)(sls::Positions) const) & (Result<sls::ns>(Detector::*)(sls::Positions) const) &
Detector::getMeasurementTime, Detector::getMeasurementTime,
py::arg() = Positions{}); py::arg() = Positions{});
CppDetectorApi.def("getUserDetails", (std::string(Detector::*)() const) &
Detector::getUserDetails);
; ;
} }

View File

@@ -20,6 +20,8 @@ void init_det(py::module &m) {
m.def("freeSharedMemory", (void (*)(const int, const int)) &sls::freeSharedMemory, py::arg() = 0, py::arg() = -1); m.def("freeSharedMemory", (void (*)(const int, const int)) &sls::freeSharedMemory, py::arg() = 0, py::arg() = -1);
m.def("getUserDetails", (std::string (*)(const int)) &sls::getUserDetails, py::arg() = 0);
py::class_<Detector> CppDetectorApi(m, "CppDetectorApi"); py::class_<Detector> CppDetectorApi(m, "CppDetectorApi");
CppDetectorApi.def(py::init<int>()); CppDetectorApi.def(py::init<int>());

View File

@@ -2466,6 +2466,15 @@ free:
PUT: PUT:
argc: 0 argc: 0
user:
is_description: true
actions:
GET:
argc: 0
PUT:
argc: 0
hostname: hostname:
is_description: true is_description: true
actions: actions:
@@ -4279,14 +4288,6 @@ initialchecks:
cast_input: [ true ] cast_input: [ true ]
output: [ args.front() ] output: [ args.front() ]
user:
help: "\n\tUser details from shared memory (hostname, type, PID, User, Date)."
actions:
GET:
argc: 0
check_det_id: true
function: getUserDetails
output: [ t ]

View File

@@ -12590,19 +12590,32 @@ user:
- arg_types: [] - arg_types: []
argc: 0 argc: 0
cast_input: [] cast_input: []
check_det_id: true check_det_id: false
convert_det_id: true convert_det_id: true
function: getUserDetails function: ''
input: [] input: []
input_types: [] input_types: []
output: output: []
- t
require_det_id: false require_det_id: false
store_result_in_t: true store_result_in_t: true
PUT:
args:
- arg_types: []
argc: 0
cast_input: []
check_det_id: false
convert_det_id: true
function: ''
input: []
input_types: []
output: []
require_det_id: false
store_result_in_t: false
command_name: user command_name: user
function_alias: user function_alias: user
help: "\n\tUser details from shared memory (hostname, type, PID, User, Date)." help: ''
infer_action: true infer_action: true
is_description: true
v_a: v_a:
actions: actions:
GET: GET:

View File

@@ -22,6 +22,10 @@ class IpAddr;
// shm by mistake // shm by mistake
void freeSharedMemory(const int detectorIndex = 0, const int moduleIndex = -1); void freeSharedMemory(const int detectorIndex = 0, const int moduleIndex = -1);
// Free function to avoid dependence on class
// and get user details directly from shm
std::string getUserDetails(const int detectorIndex = 0);
/** /**
* \class Detector * \class Detector
*/ */
@@ -2137,10 +2141,6 @@ class Detector {
* start [Gotthard2] not in burst and auto mode */ * start [Gotthard2] not in burst and auto mode */
Result<ns> getMeasurementTime(Positions pos = {}) const; Result<ns> getMeasurementTime(Positions pos = {}) const;
/** get user details from shared memory (hostname, type, PID, User, Date)
*/
std::string getUserDetails() const;
///@} ///@}
private: private:

View File

@@ -16316,48 +16316,6 @@ std::string Caller::updatemode(int action) {
return os.str(); return os.str();
} }
std::string Caller::user(int action) {
std::ostringstream os;
// print help
if (action == slsDetectorDefs::HELP_ACTION) {
os << R"V0G0N(
User details from shared memory (hostname, type, PID, User, Date). )V0G0N"
<< std::endl;
return os.str();
}
// check if action and arguments are valid
if (action == slsDetectorDefs::GET_ACTION) {
if (1 && args.size() != 0) {
throw RuntimeError("Wrong number of arguments for action GET");
}
if (args.size() == 0) {
}
}
else {
throw RuntimeError(
"INTERNAL ERROR: Invalid action: supported actions are ['GET']");
}
// generate code for each action
if (action == slsDetectorDefs::GET_ACTION) {
if (args.size() == 0) {
if (det_id != -1) {
throw RuntimeError("Cannot execute user at module level");
}
auto t = det->getUserDetails();
os << t << '\n';
}
}
return os.str();
}
std::string Caller::v_a(int action) { std::string Caller::v_a(int action) {
std::ostringstream os; std::ostringstream os;

View File

@@ -73,6 +73,7 @@ std::string Caller::list(int action) {
} }
if (args.empty()) { if (args.empty()) {
std::string ret = "free\n"; std::string ret = "free\n";
ret += "user\n";
for (auto &f : functions) { for (auto &f : functions) {
ret += f.first + "\n"; ret += f.first + "\n";
} }
@@ -188,6 +189,12 @@ std::string Caller::free(int action) {
return "free\n\tFree detector shared memory\n"; return "free\n\tFree detector shared memory\n";
} }
std::string Caller::user(int action) {
// This function is purely for help, actual functionality is in the caller
return "user\n\tUser details from shared memory (hostname, type, PID, "
"User, Date).\n";
}
std::string Caller::hostname(int action) { std::string Caller::hostname(int action) {
std::ostringstream os; std::ostringstream os;
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {

View File

@@ -50,14 +50,27 @@ int main(int argc, char *argv[]) {
action = slsDetectorDefs::HELP_ACTION; action = slsDetectorDefs::HELP_ACTION;
else { else {
// Free shared memory should work also without a detector // Free shared memory should work also without a detector
// if we have an option for verify in the detector constructor
// we could avoid this but clutter the code
if (parser.command() == "free") { if (parser.command() == "free") {
if (parser.detector_id() != -1) if (parser.detector_id() != -1)
std::cout << "Cannot free shared memory of sub-detector\n"; std::cout << "Cannot free shared memory of sub-detector\n";
else else
sls::freeSharedMemory(parser.multi_id()); sls::freeSharedMemory(parser.multi_id());
return 0; return EXIT_SUCCESS;
}
// Get user details from shared memory should work also without a
// detector
if (parser.command() == "user") {
if (action == slsDetectorDefs::PUT_ACTION) {
std::cout << "Cannot set user details\n";
return EXIT_FAILURE;
}
if (parser.detector_id() != -1)
std::cout << "Cannot get user details of only a sub-detector\n";
else
std::cout << sls::getUserDetails(parser.multi_id())
<< std::endl;
return EXIT_SUCCESS;
} }
} }

View File

@@ -61,6 +61,54 @@ void freeSharedMemory(const int detectorIndex, const int moduleIndex) {
} }
} }
std::string getUserDetails(const int detectorIndex) {
int numModules = 0;
defs::detectorType type = defs::GENERIC;
pid_t pid = -1;
std::string hostname = "Unknown";
std::string user = "Unknown";
std::string date = "Unknown";
SharedMemory<sharedDetector> detectorShm(detectorIndex, -1);
if (detectorShm.exists()) {
detectorShm.openSharedMemory(false);
if (detectorShm()->shmversion < DETECTOR_SHMAPIVERSION) {
detectorShm.unmapSharedMemory();
throw SharedMemoryError(
"Detector Shared memory version too old to get user details!");
}
numModules = detectorShm()->totalNumberOfModules;
type = detectorShm()->detType;
pid = detectorShm()->lastPID;
user = detectorShm()->lastUser;
date = detectorShm()->lastDate;
detectorShm.unmapSharedMemory();
}
for (int imod = 0; imod != numModules; ++imod) {
SharedMemory<sharedModule> moduleShm(detectorIndex, imod);
moduleShm.openSharedMemory(false);
if (moduleShm()->shmversion < MODULE_SHMAPIVERSION) {
LOG(logWARNING) << "Module Shared Memory too old to get hostname";
} else {
hostname = moduleShm()->hostname;
}
moduleShm.unmapSharedMemory();
}
std::ostringstream userDetails;
userDetails << "Detector Index: " << detectorIndex << "\n"
<< "Number of Modules: " << numModules << "\n"
<< "Type: " << type << "\n"
<< "PID: " << pid << "\n"
<< "User: " << user << "\n"
<< "Date: " << date << "\n"
<< "Hostname: " << hostname << "\n";
return userDetails.str();
}
using defs = slsDetectorDefs; using defs = slsDetectorDefs;
Detector::Detector(int shm_id) : pimpl(make_unique<DetectorImpl>(shm_id)) {} Detector::Detector(int shm_id) : pimpl(make_unique<DetectorImpl>(shm_id)) {}
@@ -2828,8 +2876,6 @@ Result<ns> Detector::getMeasurementTime(Positions pos) const {
return pimpl->Parallel(&Module::getMeasurementTime, pos); return pimpl->Parallel(&Module::getMeasurementTime, pos);
} }
std::string Detector::getUserDetails() const { return pimpl->getUserDetails(); }
std::vector<uint16_t> Detector::getValidPortNumbers(uint16_t start_port) { std::vector<uint16_t> Detector::getValidPortNumbers(uint16_t start_port) {
int num_sockets_per_detector = getNumberofUDPInterfaces({}).tsquash( int num_sockets_per_detector = getNumberofUDPInterfaces({}).tsquash(
"Number of UDP Interfaces is not consistent among modules"); "Number of UDP Interfaces is not consistent among modules");

View File

@@ -31,21 +31,16 @@
namespace sls { namespace sls {
DetectorImpl::DetectorImpl(int detector_index, bool verify, bool update) DetectorImpl::DetectorImpl(int detector_index)
: detectorIndex(detector_index), shm(detector_index, -1), : detectorIndex(detector_index), shm(detector_index, -1),
ctb_shm(detector_index, -1, CtbConfig::shm_tag()) { ctb_shm(detector_index, -1, CtbConfig::shm_tag()) {
setupDetector(verify, update); setupDetector();
} }
void DetectorImpl::setupDetector(bool verify, bool update) { void DetectorImpl::setupDetector() {
initSharedMemory(verify); initSharedMemory();
initializeMembers(verify); initializeMembers();
if (update) { updateUserdetails();
updateUserdetails();
}
if (ctb_shm.exists())
ctb_shm.openSharedMemory(verify);
} }
bool DetectorImpl::isAllPositions(Positions pos) const { bool DetectorImpl::isAllPositions(Positions pos) const {
@@ -57,64 +52,45 @@ void DetectorImpl::setAcquiringFlag(bool flag) { shm()->acquiringFlag = flag; }
int DetectorImpl::getDetectorIndex() const { return detectorIndex; } int DetectorImpl::getDetectorIndex() const { return detectorIndex; }
std::string DetectorImpl::getUserDetails() {
if (modules.empty()) {
return std::string("none");
}
std::ostringstream sstream;
sstream << "\nHostname: ";
for (auto &module : modules) {
sstream << (module->isFixedPatternSharedMemoryCompatible()
? module->getHostname()
: "Unknown")
<< "+";
}
sstream << "\nType: ";
// get type from detector version shm
if (shm()->shmversion >= DETECTOR_SHMAPIVERSION) {
sstream << ToString(shm()->detType);
}
// get type from module shm
else {
for (auto &module : modules) {
sstream << (module->isFixedPatternSharedMemoryCompatible()
? ToString(module->getDetectorType())
: "Unknown")
<< "+";
}
}
sstream << "\nPID: " << shm()->lastPID << "\nUser: " << shm()->lastUser
<< "\nDate: " << shm()->lastDate << std::endl;
return sstream.str();
}
bool DetectorImpl::getInitialChecks() const { return shm()->initialChecks; } bool DetectorImpl::getInitialChecks() const { return shm()->initialChecks; }
void DetectorImpl::setInitialChecks(const bool value) { void DetectorImpl::setInitialChecks(const bool value) {
shm()->initialChecks = value; shm()->initialChecks = value;
} }
void DetectorImpl::initSharedMemory(bool verify) { void DetectorImpl::initSharedMemory() {
// creating new shm
if (!shm.exists()) { if (!shm.exists()) {
shm.createSharedMemory(); shm.createSharedMemory();
initializeDetectorStructure(); initializeDetectorStructure();
} else { }
shm.openSharedMemory(verify);
if (verify && shm()->shmversion != DETECTOR_SHMVERSION) { // opening existing shm
else {
shm.openSharedMemory(true);
if (shm()->shmversion != DETECTOR_SHMVERSION) {
LOG(logERROR) << "Detector shared memory (" << detectorIndex LOG(logERROR) << "Detector shared memory (" << detectorIndex
<< ") version mismatch " << ") version mismatch "
"(expected 0x" "(expected 0x"
<< std::hex << DETECTOR_SHMVERSION << " but got 0x" << std::hex << DETECTOR_SHMVERSION << " but got 0x"
<< shm()->shmversion << std::dec << shm()->shmversion << std::dec
<< ". Clear Shared memory to continue."; << ". Free Shared memory to continue.";
throw SharedMemoryError("Shared memory version mismatch!"); shm.unmapSharedMemory();
throw SharedMemoryError("Detector Shared memory version mismatch!");
}
if (ctb_shm.exists()) {
ctb_shm.openSharedMemory(true);
if (ctb_shm()->shmversion != CTB_SHMVERSION) {
LOG(logERROR)
<< "CTB shared memory version mismatch (expected 0x"
<< std::hex << CTB_SHMVERSION << " but got 0x"
<< ctb_shm()->shmversion << std::dec
<< ". Free Shared memory to continue.";
ctb_shm.unmapSharedMemory();
throw SharedMemoryError("Ctb Shared memory version mismatch!");
}
} }
} }
// std::cout <<
} }
void DetectorImpl::initializeDetectorStructure() { void DetectorImpl::initializeDetectorStructure() {
@@ -132,14 +108,14 @@ void DetectorImpl::initializeDetectorStructure() {
shm()->zmqHwm = -1; shm()->zmqHwm = -1;
} }
void DetectorImpl::initializeMembers(bool verify) { void DetectorImpl::initializeMembers() {
// DetectorImpl // DetectorImpl
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 < shm()->totalNumberOfModules; i++) { for (int i = 0; i < shm()->totalNumberOfModules; i++) {
try { try {
modules.push_back(make_unique<Module>(detectorIndex, i, verify)); modules.push_back(make_unique<Module>(detectorIndex, i));
} catch (...) { } catch (...) {
modules.clear(); modules.clear();
throw; throw;
@@ -210,10 +186,12 @@ void DetectorImpl::setHostname(const std::vector<std::string> &name) {
if (shm()->detType == defs::CHIPTESTBOARD || if (shm()->detType == defs::CHIPTESTBOARD ||
shm()->detType == defs::XILINX_CHIPTESTBOARD) { shm()->detType == defs::XILINX_CHIPTESTBOARD) {
if (ctb_shm.exists()) if (ctb_shm.exists()) {
ctb_shm.openSharedMemory(true); throw SharedMemoryError(
else "This shared memory " + ctb_shm.getName() +
ctb_shm.createSharedMemory(); " should have been deleted before! Free it to continue.");
}
ctb_shm.createSharedMemory();
} }
} }
@@ -233,7 +211,7 @@ void DetectorImpl::addModule(const std::string &name) {
} }
auto pos = modules.size(); auto pos = modules.size();
modules.emplace_back(make_unique<Module>(type, detectorIndex, pos, false)); modules.emplace_back(make_unique<Module>(type, detectorIndex, pos));
shm()->totalNumberOfModules = modules.size(); shm()->totalNumberOfModules = modules.size();
modules[pos]->setControlPort(port); modules[pos]->setControlPort(port);
modules[pos]->setStopPort(port + 1); modules[pos]->setStopPort(port + 1);

View File

@@ -71,13 +71,7 @@ struct sharedDetector {
class DetectorImpl : public virtual slsDetectorDefs { class DetectorImpl : public virtual slsDetectorDefs {
public: public:
/** explicit DetectorImpl(int detector_index = 0);
* @param verify true to verify if shared memory version matches existing
* one
* @param update true to update last user pid, date etc
*/
explicit DetectorImpl(int detector_index = 0, bool verify = true,
bool update = true);
template <class CT> struct NonDeduced { template <class CT> struct NonDeduced {
using type = CT; using type = CT;
@@ -195,9 +189,6 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** return detector index in shared memory */ /** return detector index in shared memory */
int getDetectorIndex() const; int getDetectorIndex() const;
/** Get user details of shared memory */
std::string getUserDetails();
bool getInitialChecks() const; bool getInitialChecks() const;
/** initial compaibility and other server start up checks /** initial compaibility and other server start up checks
@@ -341,26 +332,20 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** /**
* Creates/open shared memory, initializes detector structure and members * Creates/open shared memory, initializes detector structure and members
* Called by constructor/ set hostname / read config file * Called by constructor/ set hostname / read config file
* @param verify true to verify if shared memory version matches existing
* one
* @param update true to update last user pid, date etc
*/ */
void setupDetector(bool verify = true, bool update = true); void setupDetector();
/** /**
* Creates shm and initializes shm structure OR * Creates shm and initializes shm structure OR
* Open shm and maps to structure * Open shm and maps to structure
* @param verify true to verify if shm size matches existing one
*/ */
void initSharedMemory(bool verify = true); void initSharedMemory();
/** Initialize detector structure for the shared memory just created */ /** Initialize detector structure for the shared memory just created */
void initializeDetectorStructure(); void initializeDetectorStructure();
/** Initialize members (eg. modules from shm, zmqsockets) /** Initialize members (eg. modules from shm, zmqsockets) */
* @param verify true to verify if shm size matches existing one void initializeMembers();
*/
void initializeMembers(bool verify = true);
/** Update in shm */ /** Update in shm */
void updateUserdetails(); void updateUserdetails();

View File

@@ -30,27 +30,15 @@
namespace sls { namespace sls {
// creating new shm // creating new shm
Module::Module(detectorType type, int det_id, int module_index, bool verify) Module::Module(detectorType type, int det_id, int module_index)
: moduleIndex(module_index), shm(det_id, module_index) { : moduleIndex(module_index), shm(det_id, module_index) {
createSharedMemory(type, det_id);
// ensure shared memory was not created before
if (shm.exists()) {
LOG(logWARNING) << "This shared memory should have been "
"deleted before! "
<< shm.getName() << ". Freeing it again";
shm.removeSharedMemory();
}
initSharedMemory(type, det_id, verify);
} }
// opening existing shm // opening existing shm
Module::Module(int det_id, int module_index, bool verify) Module::Module(int det_id, int module_index)
: moduleIndex(module_index), shm(det_id, module_index) { : moduleIndex(module_index), shm(det_id, module_index) {
openSharedMemory(det_id);
// getDetectorType From shm will check if existing
detectorType type = getDetectorTypeFromShm(det_id, verify);
initSharedMemory(type, det_id, verify);
} }
bool Module::isFixedPatternSharedMemoryCompatible() const { bool Module::isFixedPatternSharedMemoryCompatible() const {
@@ -3403,43 +3391,39 @@ Ret Module::sendToReceiver(int fnum, const Arg &args) {
return static_cast<const Module &>(*this).sendToReceiver<Ret>(fnum, args); return static_cast<const Module &>(*this).sendToReceiver<Ret>(fnum, args);
} }
slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id, void Module::createSharedMemory(detectorType type, int det_id) {
bool verify) { shm = SharedMemory<sharedModule>(det_id, moduleIndex);
// ensure shared memory was not created before
if (shm.exists()) {
throw SharedMemoryError(
"This shared memory " + shm.getName() +
" should have been deleted before! Free it to continue.");
}
shm.createSharedMemory();
initializeModuleStructure(type);
}
void Module::openSharedMemory(int det_id) {
shm = SharedMemory<sharedModule>(det_id, moduleIndex);
if (!shm.exists()) { if (!shm.exists()) {
throw SharedMemoryError("Shared memory " + shm.getName() + throw SharedMemoryError("Shared memory " + shm.getName() +
" does not exist.\n Corrupted Multi Shared " " does not exist.\n Corrupted Multi Shared "
"memory. Please free shared memory."); "memory. Please free shared memory.");
} }
shm.openSharedMemory(verify); shm.openSharedMemory(true);
if (verify && shm()->shmversion != MODULE_SHMVERSION) { if (shm()->shmversion != MODULE_SHMVERSION) {
std::ostringstream ss; std::ostringstream ss;
ss << "Single shared memory (" << det_id << "-" << moduleIndex ss << "Module shared memory (" << det_id << "-" << moduleIndex
<< ":)version mismatch (expected 0x" << std::hex << MODULE_SHMVERSION << ":) version mismatch (expected 0x" << std::hex
<< " but got 0x" << shm()->shmversion << ")" << std::dec << MODULE_SHMVERSION << " but got 0x" << shm()->shmversion << ")"
<< ". Clear Shared memory to continue."; << std::dec << ". Clear Shared memory to continue.";
shm.unmapSharedMemory(); shm.unmapSharedMemory();
throw SharedMemoryError(ss.str()); throw SharedMemoryError(ss.str());
} }
return shm()->detType;
}
void Module::initSharedMemory(detectorType type, int det_id, bool verify) {
shm = SharedMemory<sharedModule>(det_id, moduleIndex);
if (!shm.exists()) {
shm.createSharedMemory();
initializeModuleStructure(type);
} else {
shm.openSharedMemory(verify);
if (verify && shm()->shmversion != MODULE_SHMVERSION) {
std::ostringstream ss;
ss << "Single shared memory (" << det_id << "-" << moduleIndex
<< ":) version mismatch (expected 0x" << std::hex
<< MODULE_SHMVERSION << " but got 0x" << shm()->shmversion << ")"
<< std::dec << ". Clear Shared memory to continue.";
throw SharedMemoryError(ss.str());
}
}
} }
void Module::initializeModuleStructure(detectorType type) { void Module::initializeModuleStructure(detectorType type) {

View File

@@ -67,14 +67,11 @@ class Module : public virtual slsDetectorDefs {
* * * *
* ************************************************/ * ************************************************/
/** creating new shared memory /** creating new shared memory */
verify is if shared memory version matches existing one */ explicit Module(detectorType type, int det_id = 0, int module_index = 0);
explicit Module(detectorType type, int det_id = 0, int module_index = 0,
bool verify = true);
/** opening existing shared memory /** opening existing shared memory */
verify is if shared memory version matches existing one */ explicit Module(int det_id = 0, int module_index = 0);
explicit Module(int det_id = 0, int module_index = 0, bool verify = true);
bool isFixedPatternSharedMemoryCompatible() const; bool isFixedPatternSharedMemoryCompatible() const;
std::string getHostname() const; std::string getHostname() const;
@@ -738,13 +735,8 @@ class Module : public virtual slsDetectorDefs {
template <typename Ret, typename Arg> template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args) const; Ret sendToReceiver(int fnum, const Arg &args) const;
/** Get Detector Type from Shared Memory void createSharedMemory(detectorType type, int det_id);
verify is if shm size matches existing one */ void openSharedMemory(int det_id);
detectorType getDetectorTypeFromShm(int det_id, bool verify = true);
/** Initialize shared memory
verify is if shm size matches existing one */
void initSharedMemory(detectorType type, int det_id, bool verify = true);
/** Initialize module structure to defaults, /** Initialize module structure to defaults,
Called when new shared memory is created */ Called when new shared memory is created */

View File

@@ -4158,7 +4158,9 @@ int InferAction::updatemode() {
int InferAction::user() { int InferAction::user() {
if (args.size() == 0) { if (args.size() == 0) {
return slsDetectorDefs::GET_ACTION; throw RuntimeError(
"sls_detector is disabled for command: user with number of "
"arguments 0. Use sls_detector_get or sls_detector_put");
} }
else { else {

View File

@@ -3592,10 +3592,16 @@ TEST_CASE("frametime", "[.cmdcall]") {
TEST_CASE("user", "[.cmdcall]") { TEST_CASE("user", "[.cmdcall]") {
Detector det; Detector det;
Caller caller(&det); Caller caller(&det);
caller.call("user", {}, -1, GET); // stays the same across calls
std::ostringstream oss1, oss2, oss3;
caller.call("user", {}, -1, GET, oss1);
caller.call("user", {}, -1, GET, oss2);
caller.call("user", {}, -1, GET, oss3);
REQUIRE(oss1.str() == oss2.str());
REQUIRE(oss2.str() == oss3.str());
// This is a get only command // This is a get only command
REQUIRE_THROWS(caller.call("user", {}, -1, PUT)); // REQUIRE_THROWS(caller.call("user", {}, -1, PUT)); exit with failure
REQUIRE_NOTHROW(caller.call("user", {}, -1, GET)); REQUIRE_NOTHROW(caller.call("user", {}, -1, GET));
} }

View File

@@ -9,6 +9,7 @@ namespace sls {
using dt = slsDetectorDefs::detectorType; using dt = slsDetectorDefs::detectorType;
TEST_CASE("Construction with a defined detector type") { TEST_CASE("Construction with a defined detector type") {
freeSharedMemory(0, 0); // clean up to start test
Module m(dt::EIGER); Module m(dt::EIGER);
REQUIRE(m.getDetectorType() == dt::EIGER); REQUIRE(m.getDetectorType() == dt::EIGER);
freeSharedMemory(0, 0); // clean up freeSharedMemory(0, 0); // clean up