Per-loader watchdog for scripted algorithms. More...
#include <phosphor-tiles/include/PhosphorTiles/ScriptedAlgorithmWatchdog.h>
Public Member Functions | |
| ScriptedAlgorithmWatchdog () | |
| ~ScriptedAlgorithmWatchdog () | |
| void | arm (ScriptedAlgorithm *algo, int timeoutMs) |
Arm the watchdog for algo with a timeout of timeoutMs ms. | |
| void | disarm (ScriptedAlgorithm *algo) |
Disarm the watchdog for algo. | |
| void | unregister (ScriptedAlgorithm *algo) |
Remove algo from the watchdog tracking map. | |
| ScriptedAlgorithmWatchdog (const ScriptedAlgorithmWatchdog &)=delete | |
| ScriptedAlgorithmWatchdog & | operator= (const ScriptedAlgorithmWatchdog &)=delete |
| ScriptedAlgorithmWatchdog (ScriptedAlgorithmWatchdog &&)=delete | |
| ScriptedAlgorithmWatchdog & | operator= (ScriptedAlgorithmWatchdog &&)=delete |
Per-loader watchdog for scripted algorithms.
A single OS thread services every live ScriptedAlgorithm instance registered with this watchdog by tracking the earliest deadline across all armed algorithms and interrupting the one whose deadline expires first. Replaces the previous "one std::thread per algorithm" model (which did not scale and wasted one thread per registered script even while idle) and the previous instance() Meyer's singleton (which meant every process shared one watchdog regardless of plugin topology).
Ownership: ScriptedAlgorithmLoader holds the watchdog via std::shared_ptr and hands a shared_ptr copy to every ScriptedAlgorithm it constructs. The shared-ownership shape is required because the registry destroys algorithms via QObject::deleteLater — an algorithm's destructor (which calls unregister on this watchdog) can therefore run on a later event- loop pass, after the loader is already gone. The watchdog thread is joined in ~ScriptedAlgorithmWatchdog, which fires only when the very last shared_ptr (the loader's or a deferred-delete algo's) is released — so the "watchdog outlives every algorithm using it" invariant is maintained by reference counting rather than member- ordering.
Usage (from ScriptedAlgorithm::guardedCall):
Thread-safety: all public methods are thread-safe. The watchdog thread lives for the lifetime of the watchdog instance (joined in destructor).
| PhosphorTiles::ScriptedAlgorithmWatchdog::ScriptedAlgorithmWatchdog | ( | ) |
| PhosphorTiles::ScriptedAlgorithmWatchdog::~ScriptedAlgorithmWatchdog | ( | ) |
|
delete |
|
delete |
| void PhosphorTiles::ScriptedAlgorithmWatchdog::arm | ( | ScriptedAlgorithm * | algo, |
| int | timeoutMs | ||
| ) |
Arm the watchdog for algo with a timeout of timeoutMs ms.
If an arm entry already exists for algo (e.g. nested guardedCall), the previous entry is replaced — the watchdog always honours the most recent arm.
| void PhosphorTiles::ScriptedAlgorithmWatchdog::disarm | ( | ScriptedAlgorithm * | algo | ) |
Disarm the watchdog for algo.
Advances algo 's generation counter under the mutex so an in-flight watchdog check observes the new generation and skips the interrupt.
|
delete |
|
delete |
| void PhosphorTiles::ScriptedAlgorithmWatchdog::unregister | ( | ScriptedAlgorithm * | algo | ) |
Remove algo from the watchdog tracking map.
Called by ScriptedAlgorithm 's destructor so the watchdog thread cannot dereference a freed instance.
shared_ptr to this watchdog for its entire lifetime (see class comment). The caller of unregister is therefore still one of the owners when this method runs, so the watchdog instance is guaranteed alive across the call. Do not "optimize" the algorithm's watchdog reference to a raw or weak pointer — that would invalidate this invariant.