diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index 706d58fca..5ede9688d 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -505,6 +505,10 @@ class Detector { * * * ************************************************/ + /** interface is by 1 (primary udp interface), + * 2 for second udp interface [Eiger][Jungfrau] */ + void removeReceivers(const int udpInterface); + /** true when slsReceiver is used */ Result getUseReceiverFlag(Positions pos = {}) const; diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 0bd5179e6..c8e72ab92 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -955,6 +955,7 @@ std::string CmdProxy::ReceiverHostname(int action) { os << "[hostname or ip address]\n\t" "[hostname or ip address]:[tcp port]\n\t" "Receiver hostname or IP. Port is the receiver tcp port (optional).\n\t" + "Use 'none' to remove receivers\n\t" "Used for TCP control communication between client and receiver " "to configure receiver. Also updates receiver with detector parameters.\n\t" "TCP port must be unique, if included.\n\t" @@ -967,6 +968,7 @@ std::string CmdProxy::ReceiverHostname(int action) { "[hostname or ip address]:[tcp port]\n\t" "[Eiger][Jungfrau] Receiver hostname or IP for the second udp port. " "Port is the receiver tcp port (optional).\n\t" + "Use 'none' to remove receivers\n\t" "Refer rx_hostname help for details" << '\n'; } @@ -984,19 +986,27 @@ std::string CmdProxy::ReceiverHostname(int action) { throw sls::RuntimeError("Cannot concatenate receiver hostnames"); } std::pair res = parseHostnameAndPort(args[0]); - std::string hostname = res.first; - int port = res.second; - if (port == 0) { - det->setRxHostname(udpInterface, hostname, {det_id}); - } else { - if (det_id == -1 && det->size() > 1) { - throw sls::RuntimeError("Cannot set same tcp port " - "for all receiver hostnames"); - } - det->setRxHostname(udpInterface, hostname, port, det_id); + // removing receivers + if (res.first == "none") { + det->removeReceivers(udpInterface); + os << "removed" << '\n'; + } + // adding receivers + else { + std::string hostname = res.first; + int port = res.second; + if (port == 0) { + det->setRxHostname(udpInterface, hostname, {det_id}); + } else { + if (det_id == -1 && det->size() > 1) { + throw sls::RuntimeError("Cannot set same tcp port " + "for all receiver hostnames"); + } + det->setRxHostname(udpInterface, hostname, port, det_id); + } + auto t = det->getRxHostname(udpInterface, {det_id}); + os << OutString(t) << '\n'; } - auto t = det->getRxHostname(udpInterface, {det_id}); - os << OutString(t) << '\n'; } else { throw sls::RuntimeError("Unknown action"); } diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index e8a88b4f3..635401c60 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -691,6 +691,11 @@ void Detector::setTransmissionDelayRight(int value, Positions pos) { // Receiver +void Detector::removeReceivers(const int udpInterface) { + pimpl->removeReceivers(udpInterface); +} + + Result Detector::getUseReceiverFlag(Positions pos) const { return pimpl->Parallel(&Module::getUseReceiverFlag, pos); } @@ -702,48 +707,33 @@ Result Detector::getRxHostname(const int udpInterface, Positions po case 2: return pimpl->Parallel2(&Receiver::getHostname, pos, {0}); default: - throw RuntimeError("Invalid udp interface number"); + throw RuntimeError("Invalid udp interface number " + + std::to_string(udpInterface)); } } void Detector::setRxHostname(const int udpInterface, const std::string &hostname, Positions pos) { - switch (udpInterface) { - case 1: - if (!pimpl->isReceiverInitialized()) { - pimpl->initReceiver(); - } - pimpl->Parallel1(&Receiver::setHostname, pos, {0}, hostname); - break; - case 2: - if (!pimpl->isReceiver2Initialized()) { - pimpl->initReceiver2(); - } - pimpl->Parallel2(&Receiver::setHostname, pos, {0}, hostname); - break; - default: - throw RuntimeError("Invalid udp interface number"); + if (!pimpl->isReceiverInitialized(udpInterface)) { + pimpl->initReceiver(udpInterface); + } + if (udpInterface == 1) { + pimpl->Parallel1(&Receiver::setHostname, pos, {0}, hostname); + } else { + pimpl->Parallel2(&Receiver::setHostname, pos, {0}, hostname); } } void Detector::setRxHostname(const int udpInterface, const std::string &hostname, const int port, int module_id) { - switch (udpInterface) { - case 1: - if (!pimpl->isReceiverInitialized()) { - pimpl->initReceiver(); - } - pimpl->Parallel1(&Receiver::setTCPPort, {module_id}, {0}, port); - pimpl->Parallel1(&Receiver::setHostname, {module_id}, {0}, hostname); - break; - case 2: - if (!pimpl->isReceiver2Initialized()) { - pimpl->initReceiver2(); - } - pimpl->Parallel2(&Receiver::setTCPPort, {module_id}, {0}, port); - pimpl->Parallel2(&Receiver::setHostname, {module_id}, {0}, hostname); - break; - default: - throw RuntimeError("Invalid udp interface number"); + if (!pimpl->isReceiverInitialized(udpInterface)) { + pimpl->initReceiver(udpInterface); + } + if (udpInterface == 1) { + pimpl->Parallel1(&Receiver::setTCPPort, {module_id}, {0}, port); + pimpl->Parallel1(&Receiver::setHostname, {module_id}, {0}, hostname); + } else { + pimpl->Parallel2(&Receiver::setTCPPort, {module_id}, {0}, port); + pimpl->Parallel2(&Receiver::setHostname, {module_id}, {0}, hostname); } } @@ -754,15 +744,16 @@ Result Detector::getRxPort(const int udpInterface, Positions pos) const { case 2: return pimpl->Parallel2(&Receiver::getTCPPort, pos, {0}); default: - throw RuntimeError("Invalid udp interface number"); + throw RuntimeError("Invalid udp interface number " + + std::to_string(udpInterface)); } } void Detector::setRxPort(const int udpInterface, int port, int module_id) { + if (!pimpl->isReceiverInitialized(udpInterface)) { + pimpl->initReceiver(udpInterface); + } if (udpInterface == 1) { - if (!pimpl->isReceiverInitialized()) { - pimpl->initReceiver(); - } if (module_id == -1) { std::vector port_list = getPortNumbers(port); for (int idet = 0; idet < size(); ++idet) { @@ -772,10 +763,7 @@ void Detector::setRxPort(const int udpInterface, int port, int module_id) { } else { pimpl->Parallel1(&Receiver::setTCPPort, {module_id}, {0}, port); } - } else if (udpInterface == 2) { - if (!pimpl->isReceiver2Initialized()) { - pimpl->initReceiver2(); - } + } else { if (module_id == -1) { std::vector port_list = getPortNumbers(port); for (int idet = 0; idet < size(); ++idet) { @@ -785,8 +773,6 @@ void Detector::setRxPort(const int udpInterface, int port, int module_id) { } else { pimpl->Parallel2(&Receiver::setTCPPort, {module_id}, {0}, port); } - } else { - throw RuntimeError("Invalid udp interface number"); } } diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index cc3567b97..f891cbcfc 100755 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -361,52 +361,80 @@ void DetectorImpl::addModule(const std::string &hostname, detectors[pos]->updateNumberOfChannels(); } -void DetectorImpl::initReceiver() { - if (receivers.size() != 0) { - throw RuntimeError("receiver vector already initialized"); - } - int tcpPort = DEFAULT_RX_PORTNO; - int zmqPort = DEFAULT_ZMQ_CL_PORTNO; - try { - for (int iModule = 0; iModule < size(); ++iModule) { - receivers.resize(detectors.size()); - receivers[iModule].push_back( - sls::make_unique(detectorId, iModule, 0, - true, tcpPort++, "", zmqPort++)); - detectors[iModule]->setNumberOfReceivers(1); +void DetectorImpl::initReceiver(const int udpInterface) { + if (udpInterface == 1) { + if (receivers.size() != 0) { + throw RuntimeError("receiver vector already initialized"); } - } catch (...) { - receivers.clear(); - throw; - } -} - -bool DetectorImpl::isReceiverInitialized() { - return (receivers.size() > 0); -} - -void DetectorImpl::initReceiver2() { - if (receivers2.size() != 0) { - throw RuntimeError("receiver2 vector already initialized"); - } - int tcpPort = DEFAULT_RX_PORTNO + size(); - int zmqPort = DEFAULT_ZMQ_CL_PORTNO + size(); - try { - for (int iModule = 0; iModule < size(); ++iModule) { - receivers2.resize(detectors.size()); - receivers2[iModule].push_back( - sls::make_unique(detectorId, iModule, 0, - false, tcpPort++, "", zmqPort++)); - detectors[iModule]->setNumberOfReceivers2(1); + int tcpPort = DEFAULT_RX_PORTNO; + int zmqPort = DEFAULT_ZMQ_CL_PORTNO; + try { + for (int iModule = 0; iModule < size(); ++iModule) { + receivers.resize(detectors.size()); + receivers[iModule].push_back( + sls::make_unique(detectorId, iModule, 0, + true, tcpPort++, "", zmqPort++)); + detectors[iModule]->setNumberOfReceivers(1); + } + } catch (...) { + receivers.clear(); + throw; } - } catch (...) { - receivers.clear(); - throw; + } else if (udpInterface == 2) { + if (receivers2.size() != 0) { + throw RuntimeError("receiver2 vector already initialized"); + } + int tcpPort = DEFAULT_RX_PORTNO + size(); + int zmqPort = DEFAULT_ZMQ_CL_PORTNO + size(); + try { + for (int iModule = 0; iModule < size(); ++iModule) { + receivers2.resize(detectors.size()); + receivers2[iModule].push_back( + sls::make_unique(detectorId, iModule, 0, + false, tcpPort++, "", zmqPort++)); + detectors[iModule]->setNumberOfReceivers2(1); + } + } catch (...) { + receivers2.clear(); + throw; + } + } else { + throw RuntimeError("Invalid udp interface number " + + std::to_string(udpInterface)); } } -bool DetectorImpl::isReceiver2Initialized() { - return (receivers2.size() > 0); +bool DetectorImpl::isReceiverInitialized(const int udpInterface) { + switch (udpInterface) { + case 1: + return (receivers.size() > 0); + case 2: + return (receivers2.size() > 0); + default: + throw RuntimeError("Invalid udp interface number " + + std::to_string(udpInterface)); + } +} + +void DetectorImpl::removeReceivers(const int udpInterface) { + if (udpInterface == 1) { + for (auto & dr: receivers) { + for (auto & r : dr) { + r->freeSharedMemory(); + } + } + receivers.clear(); + } else if (udpInterface == 2) { + for (auto & dr: receivers2) { + for (auto & r : dr) { + r->freeSharedMemory(); + } + } + receivers2.clear(); + } else { + throw RuntimeError("Invalid udp interface number " + + std::to_string(udpInterface)); + } } void DetectorImpl::updateDetectorSize() { diff --git a/slsDetectorSoftware/src/DetectorImpl.h b/slsDetectorSoftware/src/DetectorImpl.h index 345ca537a..416159199 100755 --- a/slsDetectorSoftware/src/DetectorImpl.h +++ b/slsDetectorSoftware/src/DetectorImpl.h @@ -528,10 +528,9 @@ class DetectorImpl : public virtual slsDetectorDefs { void setHostname(const std::vector &name, const std::vector &port); - void initReceiver(); - bool isReceiverInitialized(); - void initReceiver2(); - bool isReceiver2Initialized(); + void initReceiver(const int udpInterface); + bool isReceiverInitialized(const int udpInterface); + void removeReceivers(const int udpInterface); /** Gets the total number of detectors */ int size() const;