Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
PhosphorTiles::ScriptedAlgorithmWatchdog Class Reference

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
 
ScriptedAlgorithmWatchdogoperator= (const ScriptedAlgorithmWatchdog &)=delete
 
 ScriptedAlgorithmWatchdog (ScriptedAlgorithmWatchdog &&)=delete
 
ScriptedAlgorithmWatchdogoperator= (ScriptedAlgorithmWatchdog &&)=delete
 

Detailed Description

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):

  1. arm(this, timeoutMs) before invoking the guarded JS callable.
  2. disarm(this) after the JS call returns — advances the instance's generation so a race with the watchdog thread is detected and the eventual ScriptedAlgorithm::interruptEngine call is suppressed.

Thread-safety: all public methods are thread-safe. The watchdog thread lives for the lifetime of the watchdog instance (joined in destructor).

Constructor & Destructor Documentation

◆ ScriptedAlgorithmWatchdog() [1/3]

PhosphorTiles::ScriptedAlgorithmWatchdog::ScriptedAlgorithmWatchdog ( )

◆ ~ScriptedAlgorithmWatchdog()

PhosphorTiles::ScriptedAlgorithmWatchdog::~ScriptedAlgorithmWatchdog ( )

◆ ScriptedAlgorithmWatchdog() [2/3]

PhosphorTiles::ScriptedAlgorithmWatchdog::ScriptedAlgorithmWatchdog ( const ScriptedAlgorithmWatchdog )
delete

◆ ScriptedAlgorithmWatchdog() [3/3]

PhosphorTiles::ScriptedAlgorithmWatchdog::ScriptedAlgorithmWatchdog ( ScriptedAlgorithmWatchdog &&  )
delete

Member Function Documentation

◆ arm()

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.

◆ disarm()

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.

◆ operator=() [1/2]

ScriptedAlgorithmWatchdog & PhosphorTiles::ScriptedAlgorithmWatchdog::operator= ( const ScriptedAlgorithmWatchdog )
delete

◆ operator=() [2/2]

ScriptedAlgorithmWatchdog & PhosphorTiles::ScriptedAlgorithmWatchdog::operator= ( ScriptedAlgorithmWatchdog &&  )
delete

◆ unregister()

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.

Invariant
Every ScriptedAlgorithm that registers here holds a 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.

The documentation for this class was generated from the following file: