|
Safe API Framework
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
|
init/execute/shutdown lifecycle entry point for applications More...
Files | |
| file | src/app/appmanager/sapi_appmanager.c |
| Application Manager implementation. | |
Data Structures | |
| struct | sapi_appmanager_operations_t |
| Application lifecycle operations. More... | |
| struct | sapi_appmanager_checkpoint_config_t |
| Optional built-in checkpoint rendezvous configuration (ADR-019/ADR-034). More... | |
| struct | sapi_appmanager_config_t |
| Application manager configuration. More... | |
| struct | sapi_appmanager_state_t |
| Application manager runtime state. More... | |
Macros | |
| #define | SAPI_APPMANAGER_CHECKPOINT_SIGNATURE_SEED ((uint64_t)0xFFFFFFFFFFFFFFFFULL) |
| Reset value of the per-cycle checkpoint signature before any marks are folded into it (ADR-034) - see sapi_appmanager_checkpoint_fold_signature()'s own doc. A cycle in which no SAPI_CHECKPOINT_MARK() call is ever made therefore always computes checkpoint_id as sapi_appmanager_checkpoint_fold_signature(SAPI_APPMANAGER_CHECKPOINT_SIGNATURE_SEED). | |
| #define | SAPI_CHECKPOINT_MARK() |
| Records a checkpoint mark for this call site (ADR-034) - see sapi_appmanager_checkpoint_mark()'s own doc. | |
| #define | SAPI_CHECKPOINT_MARK_LABEL(label_str) |
| Records a checkpoint mark identified by a caller-supplied label instead of this call site's file:line (ADR-034) - see sapi_appmanager_checkpoint_mark()'s own doc. | |
Enumerations | |
| enum | sapi_app_state_t { SAPI_APP_STATE_UNINITIALIZED = 0 , SAPI_APP_STATE_INITIALIZING = 1 , SAPI_APP_STATE_RUNNING = 2 , SAPI_APP_STATE_SHUTTING_DOWN = 3 , SAPI_APP_STATE_SHUTDOWN = 4 , SAPI_APP_STATE_ERROR = 5 } |
| Application state enumeration. More... | |
Functions | |
| uint32_t | sapi_appmanager_checkpoint_fold_signature (uint64_t signature) |
| Pure helper: folds a 64-bit checkpoint signature down to the uint32_t sapi_checkpoint_config_t::checkpoint_id expects (ADR-034). | |
| void | sapi_appmanager_checkpoint_mark (const char *file, int32_t line, const char *label) |
| Folds a hash of this call site into the current cycle's checkpoint signature (ADR-034). | |
| int | sapi_appmanager_run (const sapi_appmanager_config_t *config) |
| Run application with lifecycle management. | |
| sapi_app_state_t | sapi_appmanager_get_state (void) |
| Get current application state. | |
| sapi_status_t | sapi_appmanager_get_stats (sapi_appmanager_state_t *state) |
| Get application statistics. | |
| void | sapi_appmanager_request_shutdown (void) |
| Request application shutdown. | |
| sapi_status_t | sapi_appmanager_install_default_signal_handlers (void) |
| POSIX-only convenience: installs SIGINT and SIGTERM handlers that call sapi_appmanager_request_shutdown(), so an operator (Ctrl+C) or process manager (SIGTERM) can stop a sapi_appmanager_run() loop gracefully - shutdown() still runs, this is not a hard kill. | |
| void | sapi_appmanager_reset_state (void) |
| Forcibly resets the application manager's own bookkeeping (lifecycle state, iteration/error counters, shutdown-request flag, and the ADR-026 setup-phase lock) back to its initial, pre-run condition. | |
init/execute/shutdown lifecycle entry point for applications
| #define SAPI_APPMANAGER_CHECKPOINT_SIGNATURE_SEED ((uint64_t)0xFFFFFFFFFFFFFFFFULL) |
Reset value of the per-cycle checkpoint signature before any marks are folded into it (ADR-034) - see sapi_appmanager_checkpoint_fold_signature()'s own doc. A cycle in which no SAPI_CHECKPOINT_MARK() call is ever made therefore always computes checkpoint_id as sapi_appmanager_checkpoint_fold_signature(SAPI_APPMANAGER_CHECKPOINT_SIGNATURE_SEED).
Definition at line 341 of file sapi_appmanager.h.
| #define SAPI_CHECKPOINT_MARK | ( | ) |
Records a checkpoint mark for this call site (ADR-034) - see sapi_appmanager_checkpoint_mark()'s own doc.
Definition at line 398 of file sapi_appmanager.h.
| #define SAPI_CHECKPOINT_MARK_LABEL | ( | label_str | ) |
Records a checkpoint mark identified by a caller-supplied label instead of this call site's file:line (ADR-034) - see sapi_appmanager_checkpoint_mark()'s own doc.
Definition at line 406 of file sapi_appmanager.h.
| enum sapi_app_state_t |
Application state enumeration.
Tracks the lifecycle state of an application managed by the app manager.
Definition at line 96 of file sapi_appmanager.h.
| uint32_t sapi_appmanager_checkpoint_fold_signature | ( | uint64_t | signature | ) |
Pure helper: folds a 64-bit checkpoint signature down to the uint32_t sapi_checkpoint_config_t::checkpoint_id expects (ADR-034).
An explicit, checked fold - XOR of the signature's two 32-bit halves (CLAUDE.md: no implicit truncating cast) - not a bare narrowing assignment. Exposed as a pure, stateless function (no reference to any in-progress cycle) so a test, or an integrator's own diagnostic logging, can independently compute the expected checkpoint_id for a known signature value without needing to be inside an active sapi_appmanager_run() cycle - e.g. sapi_appmanager_checkpoint_fold_signature(SAPI_APPMANAGER_CHECKPOINT_SIGNATURE_SEED) gives the checkpoint_id for a cycle that made no marks at all.
| signature | The 64-bit signature to fold (e.g. the seed, for a no-marks cycle). |
Definition at line 159 of file sapi_appmanager.c.
| void sapi_appmanager_checkpoint_mark | ( | const char * | file, |
| int32_t | line, | ||
| const char * | label ) |
Folds a hash of this call site into the current cycle's checkpoint signature (ADR-034).
Intended to be called via SAPI_CHECKPOINT_MARK() / SAPI_CHECKPOINT_MARK_LABEL() below, not directly, so file/line are captured at the real call site. Each call computes a CRC64 hash of either label (if non-NULL) or file:line, then chains it into the running per-cycle signature: signature = crc64(encode_le(signature) || encode_le(mark_hash)) - the same explicit-little-endian-byte-pack convention sapi_checkpoint.c's own build_arrival_message() already uses, so the fold is well-defined regardless of the two channels' CPU architectures.
A no-op (does not touch the running signature) if both file and label are NULL, and outside a sapi_appmanager_run() cycle (before the loop starts, or after it ends) - safe to call unconditionally from shared code paths that might run during init()/shutdown() too.
| file | Source file of the call site (normally FILE); ignored if label is non-NULL. |
| line | Source line of the call site (normally LINE); ignored if label is non-NULL. |
| label | Optional caller-supplied identity for this mark instead of file:line (e.g. when several call sites should be treated as the same logical mark, or a single call site's mark identity should depend on which branch was taken). May be NULL to use file:line. |
Definition at line 171 of file sapi_appmanager.c.
| int sapi_appmanager_run | ( | const sapi_appmanager_config_t * | config | ) |
Run application with lifecycle management.
This is the single entry point for all applications. It manages the complete lifecycle:
Error handling:
| config | Application manager configuration |
Example (single-stage, unchanged from before ADR-019):
Example (pre/post hooks plus a built-in cross-channel checkpoint, ADR-019/ADR-034 - my_app_prepare_outputs() marks and stages, never sends directly; my_app_commit_outputs() only runs after the checkpoint confirms both channels took the same path this cycle):
Definition at line 203 of file sapi_appmanager.c.
| sapi_app_state_t sapi_appmanager_get_state | ( | void | ) |
Get current application state.
Returns the current state of a running application manager. Note: This is intended for monitoring, not for control.
Definition at line 457 of file sapi_appmanager.c.
| sapi_status_t sapi_appmanager_get_stats | ( | sapi_appmanager_state_t * | state | ) |
Get application statistics.
Returns runtime statistics (iterations, errors, etc.).
| state | Pointer to sapi_appmanager_state_t to populate |
Definition at line 462 of file sapi_appmanager.c.
| void sapi_appmanager_request_shutdown | ( | void | ) |
Request application shutdown.
Signals the application to begin shutdown. The execute loop will terminate after the current iteration.
Note: This function requests shutdown but does not guarantee immediate termination. The shutdown may take one iteration to complete.
Definition at line 472 of file sapi_appmanager.c.
| sapi_status_t sapi_appmanager_install_default_signal_handlers | ( | void | ) |
POSIX-only convenience: installs SIGINT and SIGTERM handlers that call sapi_appmanager_request_shutdown(), so an operator (Ctrl+C) or process manager (SIGTERM) can stop a sapi_appmanager_run() loop gracefully - shutdown() still runs, this is not a hard kill.
This is the one function in this module with an OS dependency - see this header's own file-level
Call this before sapi_appmanager_run() (or from init()); calling it more than once re-installs the same handlers (idempotent, matches sapi_safestate_register_handler()'s "registering again replaces the previous" convention).
Definition at line 532 of file sapi_appmanager.c.
| void sapi_appmanager_reset_state | ( | void | ) |
Forcibly resets the application manager's own bookkeeping (lifecycle state, iteration/error counters, shutdown-request flag, and the ADR-026 setup-phase lock) back to its initial, pre-run condition.
Normal use of sapi_appmanager_run() never requires this: every one of its own entry/exit paths already resets this same state on its own (see REQ-APPMANAGER-009). This function exists for the one case that bypasses those paths entirely: an application-level fault handler that itself performs a non-local jump (e.g. longjmp()) out of a SAPI_SAFESTATE_LEVEL_SAFE/_REBOOT reaction instead of the framework's own documented never-returns contract (REQ-COMMON-SAFESTATE-002). After such a jump, sapi_appmanager_run() never reaches its own SHUTDOWN phase, and this module's internal state would otherwise stay permanently stuck mid-lifecycle - causing every subsequent sapi_appmanager_run() call to be rejected by the single-entry-point guard. Call this once, immediately after regaining control via such a non-local jump, before calling sapi_appmanager_run() again.
Definition at line 477 of file sapi_appmanager.c.