|
STAR
Cal STAR — firmware, DAQ server, and engine design
|
A cancellable hold of an exact length, and nothing else. More...
#include <HoldTimer.hpp>
Public Types | |
| using | Clock = std::chrono::steady_clock |
Public Member Functions | |
| HoldTimer ()=default | |
| ~HoldTimer () | |
| HoldTimer (const HoldTimer &)=delete | |
| HoldTimer & | operator= (const HoldTimer &)=delete |
| void | start (HoldSpec spec) |
| Begin a hold. | |
| void | stop () |
| Cancel the hold and reap the timer thread. | |
| bool | extend () |
| Restart the countdown at spec.extended_ms, measured from now. | |
| bool | isActive () const |
| uint32_t | currentDurationMs () const |
| The window currently being counted – extended_ms after a successful extend(). | |
Private Member Functions | |
| void | runTimer () |
Private Attributes | |
| std::mutex | mtx_ |
| std::condition_variable | cv_ |
| std::thread | timer_thread_ |
| std::atomic< bool > | active_ {false} |
| Read without the lock by isActive() and by the wait loop, so atomic. | |
| bool | restart_ = false |
| Set by extend() to make the timer thread recompute its deadline. | |
| Clock::time_point | started_at_ {} |
| uint32_t | current_duration_ms_ = 0 |
| HoldSpec | spec_ |
A cancellable hold of an exact length, and nothing else.
Owns no I/O and knows nothing about states: it counts down and raises callbacks, and its owner decides what they mean. That is why the same object serves both the burn window and a characterization pulse – the only difference between them is the HoldSpec handed to start().
One instance per owner, not one per kind of hold. The rig occupies exactly one state at a time, so exactly one hold can be running; a second timer object would make "both armed at once" representable, and the failure mode there is a valve held open by a timer nobody is watching.
The countdown is a steady_clock deadline waited on with condition_variable::wait_until. The predecessor slept in 50 ms steps and added a nominal 50 to a counter, so it measured sleep calls rather than time: every iteration overshot, the error only ever accumulated in one direction, and a requested duration quantised to the step. A deadline cannot drift, and the wait wakes immediately on stop() instead of at the next step boundary.
Threading: start() and stop() are not safe to call concurrently with each other – the caller serialises them (SequencerService does, through transitionTo). extend() and isActive() are safe from any thread.
Definition at line 60 of file HoldTimer.hpp.
| using sequencer::HoldTimer::Clock = std::chrono::steady_clock |
Definition at line 62 of file HoldTimer.hpp.
|
default |
Referenced by HoldTimer(), and operator=().
| sequencer::HoldTimer::~HoldTimer | ( | ) |
Definition at line 7 of file HoldTimer.cpp.
References stop().
|
delete |
References HoldTimer().
| uint32_t sequencer::HoldTimer::currentDurationMs | ( | ) | const |
The window currently being counted – extended_ms after a successful extend().
Definition at line 105 of file HoldTimer.cpp.
References current_duration_ms_, lk, and mtx_.
| bool sequencer::HoldTimer::extend | ( | ) |
Restart the countdown at spec.extended_ms, measured from now.
Definition at line 88 of file HoldTimer.cpp.
References active_, current_duration_ms_, cv_, lk, mtx_, restart_, spec_, and started_at_.
Referenced by main().
|
inline |
References HoldTimer().
|
private |
Definition at line 111 of file HoldTimer.cpp.
References active_, current_duration_ms_, cv_, lk, mtx_, restart_, spec_, and started_at_.
Referenced by start().
| void sequencer::HoldTimer::start | ( | HoldSpec | spec | ) |
Begin a hold.
Supersedes any hold already running (which is stopped first, so its on_expire never fires). Returns as soon as the countdown is armed; expiry arrives on a timer thread.
Definition at line 12 of file HoldTimer.cpp.
References active_, current_duration_ms_, lk, mtx_, restart_, runTimer(), spec_, started_at_, stop(), and timer_thread_.
Referenced by main().
| void sequencer::HoldTimer::stop | ( | ) |
Cancel the hold and reap the timer thread.
Raises on_active(false) if a hold was actually running, so the "it ended" notification happens exactly once whichever way it ended. Safe to call when nothing is running, and safe to call from on_expire (see the .cpp).
Definition at line 47 of file HoldTimer.cpp.
References active_, cv_, lk, mtx_, restart_, spec_, and timer_thread_.
Referenced by main(), start(), and ~HoldTimer().
|
private |
Read without the lock by isActive() and by the wait loop, so atomic.
Definition at line 104 of file HoldTimer.hpp.
Referenced by extend(), isActive(), runTimer(), start(), and stop().
|
private |
Definition at line 108 of file HoldTimer.hpp.
Referenced by currentDurationMs(), extend(), runTimer(), and start().
|
private |
Definition at line 100 of file HoldTimer.hpp.
Referenced by extend(), runTimer(), and stop().
|
mutableprivate |
Definition at line 99 of file HoldTimer.hpp.
Referenced by currentDurationMs(), extend(), runTimer(), start(), and stop().
|
private |
Set by extend() to make the timer thread recompute its deadline.
Definition at line 106 of file HoldTimer.hpp.
Referenced by extend(), runTimer(), start(), and stop().
|
private |
Definition at line 110 of file HoldTimer.hpp.
Referenced by extend(), runTimer(), start(), and stop().
|
private |
Definition at line 107 of file HoldTimer.hpp.
Referenced by extend(), runTimer(), and start().
|
private |
Definition at line 101 of file HoldTimer.hpp.