Commit f6a882e6 authored by Alejandro Homs Puron's avatar Alejandro Homs Puron
Browse files

Do not modify Camera::Cache value until ParamReq succeeds:

* Add Cache::ChangeInfo, a specialized SuccessAck, to update
  cache value if request succeeded
* Remove MultiParamRequest::addSet because it has undefined
  behavior when multiple requests fail
parent bea10165
Pipeline #21315 failed with stages
in 1 minute and 7 seconds
......@@ -51,6 +51,11 @@ namespace lima
namespace Eiger
{
struct SuccessAck
{
void succeeded() {}
};
class SavingCtrlObj;
class Stream;
class MultiParamRequest;
......@@ -184,6 +189,18 @@ class LIBEIGER Camera : public HwMaxImageSizeCallbackGen, public EventCallbackGe
template <typename T>
struct Cache
{
struct ChangeInfo : public SuccessAck
{
ChangeInfo(Cache& c, T v) : cache(c), new_val(v)
{}
operator bool()
{ return new_val != cache.val; }
void succeeded()
{ cache.val = new_val; }
Cache& cache;
T new_val;
};
T val;
Cache() = default;
......@@ -195,8 +212,8 @@ class LIBEIGER Camera : public HwMaxImageSizeCallbackGen, public EventCallbackGe
Cache& operator =(T new_val)
{ val = new_val; return *this; }
bool changed(T new_val)
{ std::swap(val, new_val); return (val != new_val); }
ChangeInfo change(T new_val)
{ return {*this, new_val}; }
};
......@@ -208,7 +225,8 @@ class LIBEIGER Camera : public HwMaxImageSizeCallbackGen, public EventCallbackGe
int m_frames_triggered;
int m_frames_acquired;
double m_latency_time;
Cache<TrigMode> m_trig_mode;
TrigMode m_trig_mode;
Cache<std::string> m_trig_mode_name;
//- camera stuff
ApiGeneration m_api;
......
......@@ -44,6 +44,12 @@ using namespace eigerapi;
#define setParam(param, value) \
setEigerParam(*this, param, value)
#define setCachedParam(param, cache, value) \
setEigerCachedParam(*this, param, cache, value)
#define setCachedParamForce(param, cache, value, force) \
setEigerCachedParamForce(*this, param, cache, value, force)
#define getParam(param, value) \
getEigerParam(*this, param, value)
......@@ -220,14 +226,9 @@ void Camera::prepareAcq()
DEB_PARAM() << DEB_VAR3(frame_time, nb_images, nb_triggers);
MultiParamRequest synchro(*this);
if (m_frame_time.changed(frame_time))
synchro.addSet(Requests::FRAME_TIME, frame_time);
if (m_nb_images.changed(nb_images))
synchro.addSet(Requests::NIMAGES, nb_images);
if (m_nb_triggers.changed(nb_triggers))
synchro.addSet(Requests::NTRIGGER, nb_triggers);
synchro.wait();
setCachedParam(Requests::FRAME_TIME, m_frame_time, frame_time);
setCachedParam(Requests::NIMAGES, m_nb_images, nb_images);
setCachedParam(Requests::NTRIGGER, m_nb_triggers, nb_triggers);
DEB_TRACE() << "Arm start";
double timeout = 5 * 60.; // 5 min timeout
......@@ -401,8 +402,8 @@ void Camera::setTrigMode(TrigMode trig_mode) ///< [in] lima trigger mode to set
THROW_HW_ERROR(NotSupported) << DEB_VAR1(trig_mode);
}
if (m_trig_mode.changed(trig_mode))
setParam(Requests::TRIGGER_MODE,trig_name);
setCachedParam(Requests::TRIGGER_MODE, m_trig_mode_name, trig_name);
m_trig_mode = trig_mode;
}
......@@ -427,8 +428,7 @@ void Camera::setExpTime(double exp_time, ///< [in] exposure time to set
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(exp_time);
if (m_exp_time.changed(exp_time) || force)
setParam(Requests::EXPOSURE, exp_time);
setCachedParamForce(Requests::EXPOSURE, m_exp_time, exp_time, force);
}
......@@ -651,8 +651,7 @@ void Camera::_synchronize()
MultiParamRequest synchro(*this);
std::string trig_name;
synchro.addGet(Requests::TRIGGER_MODE, trig_name);
synchro.addGet(Requests::TRIGGER_MODE, m_trig_mode_name);
synchro.addGet(Requests::X_PIXEL_SIZE, m_x_pixelsize);
synchro.addGet(Requests::Y_PIXEL_SIZE, m_y_pixelsize);
......@@ -684,6 +683,7 @@ void Camera::_synchronize()
_updateImageSize();
//Trigger mode
std::string trig_name = m_trig_mode_name.value();
if(trig_name == "ints")
m_trig_mode = m_nb_triggers > 1 ? IntTrigMult : IntTrig;
else if(trig_name == "exts")
......
......@@ -49,8 +49,9 @@ class CameraRequest
public:
CameraRequest(Camera& cam) : m_cam(cam), m_requests(m_cam.m_requests) {}
template <typename A>
CommandReq doSendCommandTimeout(eigerapi::Requests::COMMAND_NAME cmd,
double timeout, DebObj *deb_ptr)
double timeout, DebObj *deb_ptr, A ack)
{
DEB_FROM_PTR(deb_ptr);
CommandReq req = m_requests->get_command(cmd);
......@@ -60,12 +61,13 @@ public:
m_requests->cancel(req);
HANDLE_EIGERERROR(req, e);
}
ack.succeeded();
return req;
}
template <typename T>
template <typename T, typename A>
ParamReq doSetParam(eigerapi::Requests::PARAM_NAME param, T value,
DebObj *deb_ptr)
DebObj *deb_ptr, A ack)
{
DEB_FROM_PTR(deb_ptr);
ParamReq req = m_requests->set_param(param, value);
......@@ -74,12 +76,13 @@ public:
} catch(const eigerapi::EigerException &e) {
HANDLE_EIGERERROR(req, e);
}
ack.succeeded();
return req;
}
template <typename T>
template <typename T, typename A>
ParamReq doGetParam(eigerapi::Requests::PARAM_NAME param, T& value,
DebObj *deb_ptr)
DebObj *deb_ptr, A ack)
{
DEB_FROM_PTR(deb_ptr);
ParamReq req = m_requests->get_param(param, value);
......@@ -89,11 +92,13 @@ public:
m_requests->cancel(req);
HANDLE_EIGERERROR(req, e);
}
ack.succeeded();
return req;
}
template <typename A>
TransferReq doStartTransfer(std::string src_file_name, std::string dest_path,
AutoMutex& lock, DebObj *deb_ptr)
AutoMutex& lock, DebObj *deb_ptr, A ack)
{
DEB_FROM_PTR(deb_ptr);
TransferReq req;
......@@ -106,6 +111,7 @@ public:
m_cam.reportEvent(event);
req.reset();
}
ack.succeeded();
return req;
}
......@@ -119,16 +125,27 @@ public:
sendEigerCommandTimeout(cam, cmd, eigerapi::CurlLoop::FutureRequest::TIMEOUT)
#define sendEigerCommandTimeout(cam, cmd, timeout) \
CameraRequest(cam).doSendCommandTimeout(cmd, timeout, DEB_PTR())
CameraRequest(cam).doSendCommandTimeout(cmd, timeout, DEB_PTR(), SuccessAck())
#define setEigerParam(cam, param, value) \
CameraRequest(cam).doSetParam(param, value, DEB_PTR())
CameraRequest(cam).doSetParam(param, value, DEB_PTR(), SuccessAck())
#define setEigerCachedParam(cam, param, cache, value) \
setEigerCachedParamForce(cam, param, cache, value, false)
#define setEigerCachedParamForce(cam, param, cache, value, force) \
do { \
auto change_info(cache.change(value)); \
if (change_info || force) \
CameraRequest(cam).doSetParam(param, value, DEB_PTR(), change_info); \
} while (0)
#define getEigerParam(cam, param, value) \
CameraRequest(cam).doGetParam(param, value, DEB_PTR())
CameraRequest(cam).doGetParam(param, value, DEB_PTR(), SuccessAck())
#define startEigerTransfer(cam, src_file_name, dest_path, lock) \
CameraRequest(cam).doStartTransfer(src_file_name, dest_path, lock, DEB_PTR())
CameraRequest(cam).doStartTransfer(src_file_name, dest_path, lock, DEB_PTR(),\
SuccessAck())
/*----------------------------------------------------------------------------
......@@ -153,10 +170,6 @@ public:
void addGet(Name name, T& var)
{ add(name, m_cam.m_requests->get_param(name, var)); }
template <typename T>
void addSet(Name name, const T& var)
{ add(name, m_cam.m_requests->set_param(name, var)); }
void wait()
{
if (m_parallel) {
......
......@@ -123,18 +123,14 @@ void SavingCtrlObj::setCommonHeader(const HwSavingCtrlObj::HeaderMap& header)
{
DEB_MEMBER_FUNCT();
MultiParamRequest synchro(m_cam);
for(HwSavingCtrlObj::HeaderMap::const_iterator i = header.begin();
i != header.end();++i)
{
std::map<std::string,int>::iterator header_index = m_availables_header_keys.find(i->first);
if(header_index == m_availables_header_keys.end())
THROW_HW_ERROR(Error) << "Header key: " << i->first << " not yet managed ";
synchro.addSet(Requests::PARAM_NAME(header_index->second),i->second);
setEigerParam(m_cam,Requests::PARAM_NAME(header_index->second),i->second);
}
synchro.wait();
}
void SavingCtrlObj::resetCommonHeader()
......@@ -185,14 +181,11 @@ void SavingCtrlObj::_prepare(int)
{
DEB_MEMBER_FUNCT();
MultiParamRequest synchro(m_cam);
int frames_per_file = int(m_frames_per_file);
DEB_TRACE() << "NIMAGES_PER_FILE:" << DEB_VAR1(frames_per_file);
synchro.addSet(Requests::NIMAGES_PER_FILE,frames_per_file);
setEigerParam(m_cam,Requests::NIMAGES_PER_FILE,frames_per_file);
DEB_TRACE() << "FILEWRITER_NAME_PATTERN" << DEB_VAR1(m_prefix);
synchro.addSet(Requests::FILEWRITER_NAME_PATTERN,m_prefix);
synchro.wait();
setEigerParam(m_cam,Requests::FILEWRITER_NAME_PATTERN,m_prefix);
AutoMutex lock(m_cond.mutex());
m_nb_file_transfer_started = m_nb_file_to_watch = 0;
......
......@@ -571,18 +571,17 @@ void Stream::_setStreamMode(bool enabled)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(enabled);
std::string enabled_str = enabled ? "enabled" : "disabled";
DEB_TRACE() << "STREAM_MODE:" << DEB_VAR1(enabled_str);
setEigerParam(m_cam,Requests::STREAM_MODE,enabled_str);
std::string enable_str = enabled ? "enabled" : "disabled";
DEB_TRACE() << "STREAM_MODE:" << DEB_VAR1(enable_str);
setEigerCachedParam(m_cam,Requests::STREAM_MODE,m_mode_str,enable_str);
}
bool Stream::_getStreamMode()
{
DEB_MEMBER_FUNCT();
std::string enabled_str;
getEigerParam(m_cam,Requests::STREAM_MODE,enabled_str);
DEB_TRACE() << "STREAM_MODE:" << DEB_VAR1(enabled_str);
bool enabled = (enabled_str == "enabled");
getEigerParam(m_cam,Requests::STREAM_MODE,m_mode_str);
DEB_TRACE() << "STREAM_MODE:" << DEB_VAR1(m_mode_str.value());
bool enabled = (m_mode_str.value() == "enabled");
DEB_RETURN() << DEB_VAR1(enabled);
return enabled;
}
......@@ -676,7 +675,7 @@ void Stream::setActive(bool active)
DEB_PARAM() << DEB_VAR1(active);
AutoMutex lock(m_cond.mutex());
DEB_TRACE() << DEB_VAR2(m_active.value(), m_state);
DEB_TRACE() << DEB_VAR2(m_active, m_state);
bool is_ready = ((m_state == Connected) || (m_state == Armed));
bool do_abort = (!active && is_ready);
......@@ -699,14 +698,13 @@ void Stream::setActive(bool active)
default:
s = "none";
}
if(m_header_detail_str.changed(s)) {
DEB_TRACE() << "STREAM_HEADER_DETAIL:" << DEB_VAR1(m_header_detail_str.value());
setEigerParam(m_cam,Requests::STREAM_HEADER_DETAIL,m_header_detail_str);
}
DEB_TRACE() << "STREAM_HEADER_DETAIL:" << DEB_VAR1(s);
setEigerCachedParam(m_cam,Requests::STREAM_HEADER_DETAIL,
m_header_detail_str,s);
}
if(m_active.changed(active))
_setStreamMode(m_active);
_setStreamMode(active);
m_active = active;
if(!m_active || is_ready)
return;
......
......@@ -100,7 +100,8 @@ namespace lima
Camera& m_cam;
mutable Cond m_cond;
Cache<bool> m_active;
bool m_active;
Cache<std::string> m_mode_str;
State m_state;
HeaderDetail m_header_detail;
Cache<std::string> m_header_detail_str;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment