Compare commits

..

1 Commits

Author SHA1 Message Date
745199c7f6 JFJochServices: Protect detector with mutex to avoid problems while detector is being configured
All checks were successful
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 12m46s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 13m45s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 13m55s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 15m48s
Build Packages / Generate python client (push) Successful in 45s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 17m44s
Build Packages / build:rpm (rocky8) (push) Successful in 17m40s
Build Packages / Create release (push) Has been skipped
Build Packages / Build documentation (push) Successful in 1m19s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 18m36s
Build Packages / build:rpm (rocky9) (push) Successful in 18m38s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 10m14s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 9m58s
Build Packages / DIALS processing test (push) Successful in 9m50s
Build Packages / Unit tests (push) Successful in 1h2m13s
2026-04-02 12:02:18 +02:00
2 changed files with 53 additions and 28 deletions

View File

@@ -18,9 +18,12 @@ void JFJochServices::Start(const DiffractionExperiment& experiment,
if (receiver != nullptr) {
logger.Info(" ... receiver start");
receiver->Start(experiment, pixel_mask, calibration);
if (detector && !experiment.IsUsingInternalPacketGen()) {
logger.Info(" ... detector start");
detector->Start(experiment);
{
std::shared_lock ul(detector_mutex);
if (detector && !experiment.IsUsingInternalPacketGen()) {
logger.Info(" ... detector start");
detector->Start(experiment);
}
}
}
@@ -28,27 +31,38 @@ void JFJochServices::Start(const DiffractionExperiment& experiment,
}
void JFJochServices::Off() {
if (detector) {
detector->Deactivate();
detector.reset();
std::unique_ptr<DetectorWrapper> old_detector;
{
std::unique_lock ul(detector_mutex);
old_detector = std::move(detector);
}
if (old_detector) {
old_detector->Deactivate();
// destroyed here, outside lock
}
}
void JFJochServices::On(DiffractionExperiment &x) {
if (x.IsUsingInternalPacketGen() || (receiver == nullptr)) {
std::unique_lock ul(detector_mutex);
detector.reset();
} else {
logger.Info("Detector on");
std::unique_ptr<DetectorWrapper> new_detector;
switch (x.GetDetectorType()) {
case DetectorType::EIGER:
case DetectorType::JUNGFRAU:
detector = std::make_unique<SLSDetectorWrapper>();
new_detector = std::make_unique<SLSDetectorWrapper>();
break;
case DetectorType::DECTRIS:
detector = std::make_unique<DectrisDetectorWrapper>();
new_detector = std::make_unique<DectrisDetectorWrapper>();
break;
}
detector->Initialize(x, receiver->GetNetworkConfig());
new_detector->Initialize(x, receiver->GetNetworkConfig());
{
std::unique_lock ul(detector_mutex);
detector = std::move(new_detector);
}
logger.Info(" ... done");
}
}
@@ -62,24 +76,28 @@ JFJochServicesOutput JFJochServices::Stop() {
if (receiver != nullptr) {
try {
if (detector) {
logger.Info("Wait for detector idle");
DetectorState state = detector->GetState();
while ((!cannot_stop_detector)
&& ((state == DetectorState::WAITING) || (state == DetectorState::BUSY))) {
// check detector state every 5 ms
std::this_thread::sleep_for(std::chrono::milliseconds(5));
state = detector->GetState();
}
if (state == DetectorState::IDLE) {
logger.Info(" ... detector idle");
receiver->Cancel(true); // cancel silently
} else {
logger.Error(" ... detector in error state");
receiver->Cancel(false);
detector_error = true;
{
std::shared_lock ul(detector_mutex);
if (detector) {
logger.Info("Wait for detector idle");
DetectorState state = detector->GetState();
while ((!cannot_stop_detector)
&& ((state == DetectorState::WAITING) || (state == DetectorState::BUSY))) {
// check detector state every 5 ms
std::this_thread::sleep_for(std::chrono::milliseconds(5));
state = detector->GetState();
}
if (state == DetectorState::IDLE) {
logger.Info(" ... detector idle");
receiver->Cancel(true); // cancel silently
} else {
logger.Error(" ... detector in error state");
receiver->Cancel(false);
detector_error = true;
}
}
}
logger.Info("Wait for receiver done");
ret.receiver_output = receiver->Stop();
@@ -117,6 +135,7 @@ JFJochServicesOutput JFJochServices::Stop() {
}
void JFJochServices::Cancel() {
std::shared_lock ul(detector_mutex);
if (detector) {
// Best effort - if detector cannot be stopped, this is OK, important to still stop receiver
try {
@@ -163,15 +182,16 @@ void JFJochServices::SetSpotFindingSettings(const SpotFindingSettings &settings)
}
void JFJochServices::Trigger() {
std::shared_lock ul(detector_mutex);
if (detector && (receiver != nullptr))
detector->Trigger();
}
std::optional<DetectorStatus> JFJochServices::GetDetectorStatus() const {
if (detector)
std::shared_lock ul(detector_mutex, std::defer_lock);
if (ul.try_lock_for(std::chrono::milliseconds(500)) && detector)
return detector->GetStatus();
else
return {};
return {};
}
std::string JFJochServices::GetPreviewJPEG(const PreviewImageSettings &settings, int64_t image_number) const {
@@ -189,6 +209,7 @@ std::string JFJochServices::GetPreviewTIFF(int64_t image_number) const {
}
void JFJochServices::ConfigureDetector(const DiffractionExperiment &experiment) {
std::unique_lock ul(detector_mutex); // While configuring detector ensure exclusive access (even though pointer is not modified here)
if (detector)
detector->Configure(experiment);
}
@@ -262,6 +283,7 @@ void JFJochServices::ClearImageBuffer() const {
}
void JFJochServices::LoadDetectorPixelMask(PixelMask &mask) {
std::shared_lock ul(detector_mutex);
if (detector)
detector->LoadPixelMask(mask);
}

View File

@@ -4,6 +4,7 @@
#ifndef JUNGFRAUJOCH_JFJOCHSERVICES_H
#define JUNGFRAUJOCH_JFJOCHSERVICES_H
#include <shared_mutex>
#include "../common/DiffractionExperiment.h"
#include "../jungfrau/JFCalibration.h"
#include "../common/Logger.h"
@@ -15,6 +16,8 @@ struct JFJochServicesOutput {
};
class JFJochServices {
mutable std::shared_timed_mutex detector_mutex;
JFJochReceiverService *receiver = nullptr;
std::unique_ptr<DetectorWrapper> detector;