Motion Master 6.0.0-alpha.86
Next-generation motion control software
Loading...
Searching...
No Matches
mm::node::DeviceManager::CycleGuard Class Reference

Holds a cyclic task's whole body open against a device-set rebuild. RT-safe. More...

#include <device_manager.h>

Public Member Functions

 CycleGuard (DeviceManager &deviceManager)
 Enters the cycle. Falsy if the bus is not activated — run no device work.
 
 ~CycleGuard ()
 Leaves the cycle, if this guard entered it.
 
 CycleGuard (const CycleGuard &)=delete
 
CycleGuardoperator= (const CycleGuard &)=delete
 
 operator bool () const
 Whether this guard entered the cycle and device access is safe now.
 

Detailed Description

Holds a cyclic task's whole body open against a device-set rebuild. RT-safe.

**GameLoop constructs one for you, around the whole task list, every cycle. A cyclic task never writes one.** It is public because the loop lives in another library, not because a task author has anything to do with it.

A cyclic task resolves its own devices and parameters (findDevice / Device::findParameter) rather than being handed them, so it must not run while scan or reset is replacing the device set it walks. The loop therefore enters the cycle first and calls no task at all when the guard is falsy:

const DeviceManager::CycleGuard cycle(deviceManager_); // in GameLoop::run
if (cycle) {
for (mm::core::CyclicTask* task : tasks_) { task->execute(ctx); }
}
Interface for work executed once per game loop cycle.
Definition cyclic_task.h:44
Holds a cyclic task's whole body open against a device-set rebuild. RT-safe.
Definition device_manager.h:404

It is the published process image that decides. Falsy means no image is published, which is the bus's "not activated" state — the same two-phase model every EtherCAT stack uses (configure, then activate; reconfiguring means deactivating first). Every control-plane operation that rebuilds the device set already unpublishes the image and then drains via stopExchange, so a guard taken after the unpublish fails and one taken before is waited out. The RT thread never blocks: it runs no tasks for those cycles, which is what the bus is doing anyway.

Never blocks, never allocates: one atomic increment and one atomic load.

Warning
Holding one across a control-plane call (scan, reset, transitionToState) deadlocks that call against its own drain. A cyclic task makes no such call, and the loop holds the guard for nothing else.

Constructor & Destructor Documentation

◆ CycleGuard() [1/2]

mm::node::DeviceManager::CycleGuard::CycleGuard ( DeviceManager deviceManager)
explicit

Enters the cycle. Falsy if the bus is not activated — run no device work.

◆ ~CycleGuard()

mm::node::DeviceManager::CycleGuard::~CycleGuard ( )

Leaves the cycle, if this guard entered it.

◆ CycleGuard() [2/2]

mm::node::DeviceManager::CycleGuard::CycleGuard ( const CycleGuard )
delete

Member Function Documentation

◆ operator bool()

mm::node::DeviceManager::CycleGuard::operator bool ( ) const
inlineexplicit

Whether this guard entered the cycle and device access is safe now.

◆ operator=()

CycleGuard & mm::node::DeviceManager::CycleGuard::operator= ( const CycleGuard )
delete

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