libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_cfg.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 * Use of this source code is governed by the ISC License.
4 *
5 * src/inc/xtc_cfg.h
6 * Typed runtime-configurable settings registry -- named, typed,
7 * bounds-checked tunables resolved at run time. Each variable has:
8 * - a name (string key)
9 * - a type (int, int64, double, bool, string, enum)
10 * - a default value
11 * - optional min/max bounds
12 * - an optional validator callback
13 * - an optional change callback
14 *
15 * Use cases:
16 * - Tunable knobs that ops can change at runtime without
17 * restart (e.g. log level, backpressure thresholds).
18 * - Configuration discovery (a "show all" surface).
19 * - Test-time fault injection (set a knob in a test, restore
20 * in cleanup).
21 *
22 * Storage model:
23 * - Single global registry keyed by name.
24 * - Mutex-protected list (linear scan; suitable for ~hundreds
25 * of vars; M11.5 swaps in xtc_chash for thousands).
26 * - Each var holds its declared type + current value via union.
27 *
28 * Not yet implemented: per-session/per-database scoping (an
29 * override-stack model that needs the M16 session layer).
30 * Configuration-file parsing (xtc_cfg_load_file) and SIGHUP-driven
31 * reload (xtc_cfg_reload) are done. See docs/KNOWN_ISSUES.md for
32 * tracking.
33 */
34
35#ifndef XTC_CFG_H
36#define XTC_CFG_H
37
38#include "xtc_export.h"
39
40#include <stddef.h>
41#include <stdint.h>
42
43#include "xtc.h"
44
45typedef enum xtc_cfg_kind {
46 XTC_CFG_BOOL = 1,
47 XTC_CFG_INT = 2,
48 XTC_CFG_INT64 = 3,
49 XTC_CFG_DOUBLE = 4,
50 XTC_CFG_STRING = 5,
51 XTC_CFG_ENUM = 6
52} xtc_cfg_kind_t;
53
54typedef int (*xtc_cfg_validator_fn)(const void *new_val, void *user);
55typedef void (*xtc_cfg_changed_fn)(const char *name, const void *old_val,
56 const void *new_val, void *user);
57
58/* Spec used at registration time. */
59typedef struct xtc_cfg_spec {
60 const char *name;
61 const char *short_desc; /* ops-friendly description */
62 xtc_cfg_kind_t kind;
63
64 /* Default value (interpreted per kind). */
65 union {
66 int d_bool; /* 0/1 */
67 int d_int;
68 int64_t d_int64;
69 double d_double;
70 const char *d_string;
71 int d_enum;
72 } dflt;
73
74 /* Bounds for numeric types (inclusive); 0/0 means unbounded. */
75 int64_t min_int;
76 int64_t max_int;
77 double min_double;
78 double max_double;
79
80 /* For ENUM: NULL-terminated array of allowed string labels;
81 * the int value is the index into this array. */
82 const char *const *enum_labels;
83 int n_enum_labels;
84
85 /* Optional callbacks. */
86 xtc_cfg_validator_fn validator;
87 xtc_cfg_changed_fn on_change;
88 void *cb_user;
90
91/*
92 * PUBLIC: int xtc_cfg_register __P((const xtc_cfg_spec_t *));
93 * PUBLIC: int xtc_cfg_unregister __P((const char *));
94 *
95 * PUBLIC: int xtc_cfg_get_bool __P((const char *, int *));
96 * PUBLIC: int xtc_cfg_get_int __P((const char *, int *));
97 * PUBLIC: int xtc_cfg_get_int64 __P((const char *, int64_t *));
98 * PUBLIC: int xtc_cfg_get_double __P((const char *, double *));
99 * PUBLIC: int xtc_cfg_get_string __P((const char *, const char **));
100 * PUBLIC: int xtc_cfg_get_enum __P((const char *, int *));
101 *
102 * PUBLIC: int xtc_cfg_set_bool __P((const char *, int));
103 * PUBLIC: int xtc_cfg_set_int __P((const char *, int));
104 * PUBLIC: int xtc_cfg_set_int64 __P((const char *, int64_t));
105 * PUBLIC: int xtc_cfg_set_double __P((const char *, double));
106 * PUBLIC: int xtc_cfg_set_string __P((const char *, const char *));
107 * PUBLIC: int xtc_cfg_set_enum __P((const char *, int));
108 *
109 * PUBLIC: int xtc_cfg_count __P((void));
110 * PUBLIC: int xtc_cfg_kind __P((const char *, xtc_cfg_kind_t *));
111 * PUBLIC: int xtc_cfg_load_file __P((const char *));
112 * PUBLIC: int xtc_cfg_reload __P((void));
113 */
114
115XTC_API int xtc_cfg_register(const xtc_cfg_spec_t *spec);
116XTC_API int xtc_cfg_unregister(const char *name);
117
118XTC_API int xtc_cfg_get_bool(const char *name, int *out);
119XTC_API int xtc_cfg_get_int(const char *name, int *out);
120XTC_API int xtc_cfg_get_int64(const char *name, int64_t *out);
121XTC_API int xtc_cfg_get_double(const char *name, double *out);
122XTC_API int xtc_cfg_get_string(const char *name, const char **out);
123XTC_API int xtc_cfg_get_enum(const char *name, int *out);
124
125XTC_API int xtc_cfg_set_bool(const char *name, int v);
126XTC_API int xtc_cfg_set_int(const char *name, int v);
127XTC_API int xtc_cfg_set_int64(const char *name, int64_t v);
128XTC_API int xtc_cfg_set_double(const char *name, double v);
129XTC_API int xtc_cfg_set_string(const char *name, const char *v);
130XTC_API int xtc_cfg_set_enum(const char *name, int v);
131
132XTC_API int xtc_cfg_count(void);
133XTC_API int xtc_cfg_kind(const char *name, xtc_cfg_kind_t *out);
134
135/* Load a postgresql.conf-style `name = value` file: per-line, with `#`
136 * comments and optional quotes; each value parsed per the variable's
137 * registered kind and applied via xtc_cfg_set_* (bounds/validators
138 * apply). Unknown names and bad values are skipped. Returns the
139 * count applied (>= 0), XTC_E_INVAL (NULL path), or XTC_E_IO (open
140 * failed). Remembers the path for xtc_cfg_reload. */
141XTC_API int xtc_cfg_load_file(const char *path);
142
143/* Re-read the file last loaded by xtc_cfg_load_file. Meant to back a
144 * SIGHUP handler, but is NOT async-signal-safe (uses stdio and the
145 * registry lock): set a flag in the handler and call this from the
146 * event loop. Returns the applied count, XTC_E_INVAL (no file loaded),
147 * or XTC_E_IO. */
148XTC_API int xtc_cfg_reload(void);
149
150#endif /* XTC_CFG_H */