28static _Atomic(
options_t *) g_options = NULL;
41static mutex_t g_options_write_mutex;
46static bool g_options_initialized =
false;
65#define MAX_DEFERRED_FREES 64
67static size_t g_deferred_free_count = 0;
68static mutex_t g_deferred_free_mutex;
75static void deferred_free_add(
options_t *old_opts) {
83 g_deferred_frees[g_deferred_free_count++] = old_opts;
84 log_debug(
"Added options struct %p to deferred free list (count=%zu)", (
void *)old_opts, g_deferred_free_count);
100static void deferred_free_all(
void) {
103 log_debug(
"Freeing %zu deferred options structs", g_deferred_free_count);
105 for (
size_t i = 0; i < g_deferred_free_count; i++) {
109 g_deferred_free_count = 0;
118 if (g_options_initialized) {
119 log_warn(
"Options state already initialized");
124 if (
mutex_init(&g_options_write_mutex) != 0) {
129 if (
mutex_init(&g_deferred_free_mutex) != 0) {
143 memset(initial_opts, 0,
sizeof(*initial_opts));
168 atomic_store_explicit(&g_options, initial_opts, memory_order_release);
170 g_options_initialized =
true;
171 log_debug(
"Options state initialized with RCU pattern");
181 if (!g_options_initialized) {
186 options_t *current = atomic_load_explicit(&g_options, memory_order_acquire);
191 memcpy(current, opts,
sizeof(
options_t));
193 log_debug(
"Options state set from parsed struct");
198 if (!g_options_initialized) {
203 options_t *current = atomic_load_explicit(&g_options, memory_order_acquire);
206 atomic_store_explicit(&g_options, NULL, memory_order_release);
218 g_options_initialized =
false;
219 log_debug(
"Options state shutdown complete");
225 options_t *current = atomic_load_explicit(&g_options, memory_order_acquire);
229 log_fatal(
"Options not initialized! Call options_state_init() first");
230 log_warn(
"options_get() called before options initialization - this will cause a crash");
242 if (!g_options_initialized) {
250 options_t *old_opts = atomic_load_explicit(&g_options, memory_order_acquire);
260 memcpy(new_opts, old_opts,
sizeof(
options_t));
263 updater(new_opts, context);
267 atomic_store_explicit(&g_options, new_opts, memory_order_release);
270 deferred_free_add(old_opts);
274 log_debug(
"Options updated via RCU (old=%p, new=%p)", (
void *)old_opts, (
void *)new_opts);
288static void dimensions_updater(
options_t *opts,
void *context) {
299static void color_mode_updater(
options_t *opts,
void *context) {
308static void render_mode_updater(
options_t *opts,
void *context) {
317static void log_level_updater(
options_t *opts,
void *context) {
🔌 Cross-platform abstraction layer umbrella header for ascii-chat
⚠️‼️ Error and/or exit() when things go bad.
#define SAFE_STRNCPY(dst, src, size)
#define SAFE_MALLOC(size, cast)
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
asciichat_error_t
Error and exit codes - unified status values (0-255)
#define log_warn(...)
Log a WARN message.
#define log_fatal(...)
Log a FATAL message.
log_level_t
Logging levels enumeration.
#define log_debug(...)
Log a DEBUG message.
#define COLOR_MODE_AUTO
Backward compatibility aliases for color mode enum values.
#define OPT_MICROPHONE_INDEX_DEFAULT
Default microphone device index (-1 means system default)
#define OPT_RECONNECT_ATTEMPTS_DEFAULT
Default reconnect attempts (-1 means auto/infinite)
#define OPT_COMPRESSION_LEVEL_DEFAULT
Default compression level (1-9)
#define OPT_ADDRESS6_DEFAULT
Default IPv6 server address.
asciichat_error_t options_set_dimensions(unsigned short int width, unsigned short int height)
Update terminal dimensions.
asciichat_error_t options_set_color_mode(terminal_color_mode_t mode)
Update color mode.
const options_t * options_get(void)
Get current options (lock-free read)
asciichat_error_t options_set_log_level(log_level_t level)
Update log level.
#define OPT_PORT_DEFAULT
Default TCP port for client/server communication.
#define OPT_WEBCAM_INDEX_DEFAULT
Default webcam device index.
asciichat_error_t options_set_render_mode(render_mode_t mode)
Update render mode.
#define SNAPSHOT_DELAY_DEFAULT
Default snapshot delay in seconds.
asciichat_error_t options_update(void(*updater)(options_t *, void *), void *context)
Update options using copy-on-write (thread-safe)
#define OPT_MAX_CLIENTS_DEFAULT
Default maximum concurrent clients (server only)
#define OPT_ADDRESS_DEFAULT
Default server address for client connections.
#define OPT_SPEAKERS_INDEX_DEFAULT
Default speakers device index (-1 means system default)
📝 Logging API with multiple log levels and terminal output control
void options_state_shutdown(void)
Shutdown RCU options system.
asciichat_error_t options_state_init(void)
Initialize RCU options system.
#define MAX_DEFERRED_FREES
asciichat_error_t options_state_set(const options_t *opts)
Set options from a parsed options struct.
unsigned short int height
Consolidated options structure.
terminal_color_mode_t color_mode
Color mode (auto/none/16/256/truecolor)
char port[256]
Server port number.
int compression_level
zstd compression level (1-9)
int microphone_index
Microphone device index (-1 = default)
unsigned short int webcam_index
Webcam device index (0 = first)
unsigned short int width
Terminal width in characters.
log_level_t log_level
Log level threshold.
unsigned short int height
Terminal height in characters.
int max_clients
Maximum concurrent clients (server only)
render_mode_t render_mode
Render mode (foreground/background/half-block)
char address6[256]
IPv6 bind address (server only)
int speakers_index
Speakers device index (-1 = default)
double snapshot_delay
Snapshot delay in seconds.
int reconnect_attempts
Number of reconnection attempts (-1=infinite, 0=none)
char address[256]
Server address (client) or bind address (server)
Common SIMD utilities and structures.