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 <stddef.h>
39#include <stdint.h>
40
41#include "xtc.h"
42
43typedef enum xtc_cfg_kind {
44 XTC_CFG_BOOL = 1,
45 XTC_CFG_INT = 2,
46 XTC_CFG_INT64 = 3,
47 XTC_CFG_DOUBLE = 4,
48 XTC_CFG_STRING = 5,
49 XTC_CFG_ENUM = 6
50} xtc_cfg_kind_t;
51
52typedef int (*xtc_cfg_validator_fn)(const void *new_val, void *user);
53typedef void (*xtc_cfg_changed_fn)(const char *name, const void *old_val,
54 const void *new_val, void *user);
55
56/* Spec used at registration time. */
57typedef struct xtc_cfg_spec {
58 const char *name;
59 const char *short_desc; /* ops-friendly description */
60 xtc_cfg_kind_t kind;
61
62 /* Default value (interpreted per kind). */
63 union {
64 int d_bool; /* 0/1 */
65 int d_int;
66 int64_t d_int64;
67 double d_double;
68 const char *d_string;
69 int d_enum;
70 } dflt;
71
72 /* Bounds for numeric types (inclusive); 0/0 means unbounded. */
73 int64_t min_int;
74 int64_t max_int;
75 double min_double;
76 double max_double;
77
78 /* For ENUM: NULL-terminated array of allowed string labels;
79 * the int value is the index into this array. */
80 const char *const *enum_labels;
81 int n_enum_labels;
82
83 /* Optional callbacks. */
84 xtc_cfg_validator_fn validator;
85 xtc_cfg_changed_fn on_change;
86 void *cb_user;
88
89/*
90 * PUBLIC: int xtc_cfg_register __P((const xtc_cfg_spec_t *));
91 * PUBLIC: int xtc_cfg_unregister __P((const char *));
92 *
93 * PUBLIC: int xtc_cfg_get_bool __P((const char *, int *));
94 * PUBLIC: int xtc_cfg_get_int __P((const char *, int *));
95 * PUBLIC: int xtc_cfg_get_int64 __P((const char *, int64_t *));
96 * PUBLIC: int xtc_cfg_get_double __P((const char *, double *));
97 * PUBLIC: int xtc_cfg_get_string __P((const char *, const char **));
98 * PUBLIC: int xtc_cfg_get_enum __P((const char *, int *));
99 *
100 * PUBLIC: int xtc_cfg_set_bool __P((const char *, int));
101 * PUBLIC: int xtc_cfg_set_int __P((const char *, int));
102 * PUBLIC: int xtc_cfg_set_int64 __P((const char *, int64_t));
103 * PUBLIC: int xtc_cfg_set_double __P((const char *, double));
104 * PUBLIC: int xtc_cfg_set_string __P((const char *, const char *));
105 * PUBLIC: int xtc_cfg_set_enum __P((const char *, int));
106 *
107 * PUBLIC: int xtc_cfg_count __P((void));
108 * PUBLIC: int xtc_cfg_kind __P((const char *, xtc_cfg_kind_t *));
109 * PUBLIC: int xtc_cfg_load_file __P((const char *));
110 * PUBLIC: int xtc_cfg_reload __P((void));
111 */
112
113int xtc_cfg_register(const xtc_cfg_spec_t *spec);
114int xtc_cfg_unregister(const char *name);
115
116int xtc_cfg_get_bool(const char *name, int *out);
117int xtc_cfg_get_int(const char *name, int *out);
118int xtc_cfg_get_int64(const char *name, int64_t *out);
119int xtc_cfg_get_double(const char *name, double *out);
120int xtc_cfg_get_string(const char *name, const char **out);
121int xtc_cfg_get_enum(const char *name, int *out);
122
123int xtc_cfg_set_bool(const char *name, int v);
124int xtc_cfg_set_int(const char *name, int v);
125int xtc_cfg_set_int64(const char *name, int64_t v);
126int xtc_cfg_set_double(const char *name, double v);
127int xtc_cfg_set_string(const char *name, const char *v);
128int xtc_cfg_set_enum(const char *name, int v);
129
130int xtc_cfg_count(void);
131int xtc_cfg_kind(const char *name, xtc_cfg_kind_t *out);
132
133/* Load a postgresql.conf-style `name = value` file: per-line, with `#`
134 * comments and optional quotes; each value parsed per the variable's
135 * registered kind and applied via xtc_cfg_set_* (bounds/validators
136 * apply). Unknown names and bad values are skipped. Returns the
137 * count applied (>= 0), XTC_E_INVAL (NULL path), or XTC_E_IO (open
138 * failed). Remembers the path for xtc_cfg_reload. */
139int xtc_cfg_load_file(const char *path);
140
141/* Re-read the file last loaded by xtc_cfg_load_file. Meant to back a
142 * SIGHUP handler, but is NOT async-signal-safe (uses stdio and the
143 * registry lock): set a flag in the handler and call this from the
144 * event loop. Returns the applied count, XTC_E_INVAL (no file loaded),
145 * or XTC_E_IO. */
146int xtc_cfg_reload(void);
147
148#endif /* XTC_CFG_H */