|
Safe API Framework 0.1.0 build 384e6ae
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
|
Process-wide application setup-phase lock (ADR-026). More...
Go to the source code of this file.
Functions | |
| void | rte_lifecycle_lock (void) |
| Locks the application's setup phase. | |
| void | rte_lifecycle_unlock (void) |
| Unlocks the application's setup phase (setup is allowed again). | |
| bool | rte_lifecycle_is_locked (void) |
| rte_status_t | rte_lifecycle_check_setup_allowed (void) |
| Convenience check for a setup-only constructor: call this as one of the first checks in any function that creates/registers a new long-lived resource (a timer, channel, voter, cross-comparator, or watchdog - see this file's own header for the excluded netlink/dual exceptions). | |
Process-wide application setup-phase lock (ADR-026).
A safety-critical application shall have a well-defined INIT phase (create timers, channels, voters, cross-comparators, watchdogs) that completes before its RUN phase begins - and once RUN has begun, no further such construction is legitimate: an application whose resource set can still change while it is executing cyclically is not one whose behavior can be fully verified ahead of time.
rte_appmanager_run() is this framework's own INIT/RUN boundary: it calls rte_lifecycle_lock() the moment ops->init() returns successfully (see that function's own doc) and rte_lifecycle_unlock() at the very start of every call (mirroring its own existing g_app_state reset - see rte_appmanager.c). Every setup-only constructor this framework ships (rte_timer_create(), rte_channel_init(), rte_voter_init()/_register_channel(), rte_cross_comparator_init()/_register_channel(), rte_watchdog_create()) calls rte_lifecycle_check_setup_allowed() as one of its own first checks and returns RTE_STATUS_INVALID_STATE once locked - see each function's own doc for exactly where.
Deliberately excluded (ADR-026 section 3): rte_netlink_open(), rte_dual_channel_init(), and rte_dual_negotiator_init() are NOT gated by this lock. All three are legitimately re-invoked after RUN has begun by an application's own reconnect-after-link-loss logic (e.g. RBC_GP's former channel_ab_io.c/channel_ab_negotiate_reconnect()), which is re-establishing a link the application already owns, not adding a new one the application's own design never accounted for - see ADR-026 for the full rationale on why that distinction, not the "called after RUN" timing alone, is what this lock actually polices.
This is a single, process-wide flag (ADR-026 section 2, same single-instance assumption rte_appmanager's own g_app_state already makes - see that module's own file header) - not one lock per rte_appmanager_config_t, since this framework has no concept of more than one concurrently-running application per process today.
REQ-LIFECYCLE-001: setup-only constructors shall reject their call with RTE_STATUS_INVALID_STATE once the application's setup phase has been locked. REQ-LIFECYCLE-003: a rejected setup-only call shall be reported through rte_safestate_enter(RTE_SAFESTATE_LEVEL_DEGRADED, RTE_SAFESTATE_REASON_SETUP_AFTER_INIT, ...) before returning RTE_STATUS_INVALID_STATE (OSA model: a resource created after initialisation is a critical error reported to the platform's diagnostics). Gated since 2026-10-02 as well: rte_task_create(), rte_task_start(), rte_timer_start(), rte_ipc_create(), rte_nvm_open(), rte_channel_service_setup() (a POSIX task/timer start creates a thread). REQ-LIFECYCLE-002: the setup-phase lock shall be a plain, unsynchronized global (no dynamic allocation, no OS dependency) - this module has no OS dependency of its own, matching rte_safestate's own posture (ADR-002 section 4).
Definition in file rte_lifecycle.h.