Covers the half of the deadlock fix that decides whether a collection poisons the ones after
it. outside_fifo fills whenever the detector keeps streaming past the point where the run
stopped consuming - the analysis threads have gone, and Suspend() only arrives once Stop() has
finished with the writer - and the CBOR thread then parks in PutBlocking on the full queue.
Suspend() cannot release it, since the flag is tested before the put, so ResumeAndClear at the
next start has to; nothing else ever would, because a Get on an empty queue notifies no
producer. Without that notify the puller is dead for good: cbor_fifo fills behind it, the
puller thread blocks in turn, and every later collection receives nothing at all - no images
and no start message - while the puller itself looks healthy.
The test fails with the c_full notify in ThreadSafeFIFO::Clear removed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012bew392LTGP2fkhfRJsMcB
A re-initialisation left the previous run's ZMQImagePuller connected: JFJochServices::On
replaces its own shared_ptr, but JFJochReceiverService keeps a second reference to the puller
of the last run. Two PULL sockets on one PUSH peer share messages round-robin, so the orphaned
puller silently took half of the DECTRIS stream - the start message included - and the receiver
then waited for a start message that had already been discarded.
Once such a run was cancelled, nothing drained the orphaned puller's outside_fifo any more. Its
CBOR thread parked in PutBlocking on the full queue (suspend is only tested before the put), the
puller thread backed up behind it in cbor_fifo, and neither could reach the disconnect flag
again. The next JFJochReceiverService::Start dropped the last reference to that puller, so
~ZMQImagePuller joined two threads that could never exit - while holding state_mutex, inside a
calibration sequence that itself holds the state machine's mutex. The whole control plane froze
with no way to cancel; only a restart got out of it.
* ThreadSafeFIFO gains Stop(), which releases every waiter and makes further blocking operations
return at once. Clear() now notifies c_full as well: clearing a full queue used to leave the
blocked producer asleep, since the next Get on an empty queue notifies no one.
* ZMQImagePuller::Disconnect and TCPImagePuller::Disconnect stop their queues before joining, so
a puller whose consumer is gone can always shut down.
* JFJochServices::On and ::Off disconnect the previous puller explicitly rather than relying on
the shared_ptr going away, so two readers never share the detector stream.
ZMQImagePuller_DisconnectWithFullQueue covers the shutdown; it hangs on the previous code.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012bew392LTGP2fkhfRJsMcB
This is an UNSTABLE release. The release has significant modifications and bug fixes, if things go wrong, it is better to revert to 1.0.0-rc.124.
* jfjoch_broker: Significant improvements in TCP image socket, as a viable alternative for ZeroMQ sockets (only a single port on broker side, dynamically change number of writers, acknowledgments for written files)
* jfjoch_broker: Delta phi is calculated also for still data in Bragg prediction
* jfjoch_broker: Image pusher statistics are accessible via the REST interface
* jfjoch_writer: Supports TCP image socket and for these auto-forking option
Reviewed-on: #36
Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
Co-committed-by: Filip Leonarski <filip.leonarski@psi.ch>
This is an UNSTABLE release and not recommended for production use (please use rc.96 instead).
* jfjoch_broker: For DECTRIS detectors add dark data collection during initialization for bad pixel mask
* jfjoch_broker: Refactor of calibration logic for more clear code (likely to introduce problems)
* jfjoch_viewer: Add option to handle user pixel mask (experimental)
* jfjoch_viewer: More options for ROI
* jfjoch_viewer: Add window to display calibration
Reviewed-on: #2
Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
Co-committed-by: Filip Leonarski <filip.leonarski@psi.ch>