ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
common.c
Go to the documentation of this file.
1
8// Platform abstraction includes memory sizing functions
9#include "common.h"
10#include "platform/system.h"
11#include "platform/init.h"
12#include "platform/memory.h"
13#include "log/logging.h"
14#include "buffer_pool.h"
15#include "video/palette.h"
16#include "asciichat_errno.h"
17#include "crypto/known_hosts.h"
18#include "options/options.h"
19#include "options/rcu.h" // For RCU-based options access
20#include <string.h>
21#include <stdatomic.h>
22#include <limits.h>
23#include <stdlib.h>
24
25#ifndef _WIN32
26#include <pthread.h> // For PTHREAD_MUTEX_INITIALIZER on POSIX
27#endif
28
29// Global frame rate variable - can be set via command line
30int g_max_fps = 0; // 0 means use default
31
32/* ============================================================================
33 * Shutdown Check System Implementation
34 * ============================================================================
35 */
36
37// Use atomic for thread-safe access to shutdown callback
38#include <stdatomic.h>
39static _Atomic(shutdown_check_fn) g_shutdown_callback = NULL;
40
42 atomic_store(&g_shutdown_callback, callback);
43}
44
46 shutdown_check_fn callback = atomic_load(&g_shutdown_callback);
47 if (callback == NULL) {
48 return false; // No callback registered, assume not shutting down
49 }
50 return callback();
51}
52
53/* ============================================================================
54 * Shared Initialization Implementation
55 * ============================================================================
56 */
57
58#if defined(DEBUG_MEMORY) && !defined(USE_MIMALLOC_DEBUG) && !defined(NDEBUG)
59#include "debug/memory.h"
60#elif defined(USE_MIMALLOC_DEBUG) && !defined(NDEBUG)
61static void print_mimalloc_stats(void);
62#endif
63
64asciichat_error_t asciichat_shared_init(const char *default_log_filename, bool is_client) {
65 // Register memory debugging stats FIRST so it runs LAST at exit
66 // (atexit callbacks run in LIFO order - last registered runs first)
67 // This ensures all cleanup handlers run before the memory report is printed
68#if defined(DEBUG_MEMORY) && !defined(USE_MIMALLOC_DEBUG) && !defined(NDEBUG)
69 (void)atexit(debug_memory_report);
70#elif defined(USE_MIMALLOC_DEBUG) && !defined(NDEBUG)
71 (void)atexit(print_mimalloc_stats);
72 UNUSED(print_mimalloc_stats);
73#endif
74
75 // Initialize platform-specific functionality (Winsock, etc)
76 if (platform_init() != ASCIICHAT_OK) {
77 FATAL(ERROR_PLATFORM_INIT, "Failed to initialize platform");
78 }
79 (void)atexit(platform_cleanup);
80
81 // Apply quiet mode setting BEFORE log_init so initialization messages are suppressed
82 if (GET_OPTION(quiet)) {
84 }
85
86 // Initialize logging with default filename
87 // Client mode: route ALL logs to stderr to keep stdout clean for ASCII art output
88 const options_t *opts = options_get();
89 const char *log_file = opts && opts->log_file[0] != '\0' ? opts->log_file : default_log_filename;
90 // Use log_level from parsed options (set by options_init)
91 // Default levels (when no --log-level arg or LOG_LEVEL env var):
92 // Debug/Dev builds: LOG_DEBUG
93 // Release/RelWithDebInfo builds: LOG_INFO
94 // Precedence: LOG_LEVEL env var > --log-level CLI arg > build type default
95 // use_mmap=true: Lock-free mmap logging for performance and crash safety
96 log_init(log_file, GET_OPTION(log_level), is_client, true /* use_mmap */);
97
98 // Initialize palette based on command line options
99 const char *custom_chars = opts && opts->palette_custom_set ? opts->palette_custom : NULL;
100 if (apply_palette_config(GET_OPTION(palette_type), custom_chars) != 0) {
101 FATAL(ERROR_CONFIG, "Failed to apply palette configuration");
102 }
103
104 // Initialize global shared buffer pool
106 (void)atexit(buffer_pool_cleanup_global);
107
108 // Register errno cleanup
109 (void)atexit(asciichat_errno_cleanup);
110
111 // Register options state cleanup
112 (void)atexit(options_state_shutdown);
113
114 // Register known_hosts cleanup
115 (void)atexit(known_hosts_cleanup);
116
117 // Truncate log if it's already too large
119
120 // Set quiet mode for memory debugging (registration done at function start)
121#if defined(DEBUG_MEMORY) && !defined(USE_MIMALLOC_DEBUG) && !defined(NDEBUG)
122 debug_memory_set_quiet_mode(GET_OPTION(quiet));
123#endif
124
125 return ASCIICHAT_OK;
126}
127
128#if defined(USE_MIMALLOC_DEBUG) && !defined(NDEBUG)
129// Wrapper function for mi_stats_print to use with atexit()
130// mi_stats_print takes a parameter, but atexit requires void(void)
131static void print_mimalloc_stats(void) {
132 mi_stats_print(NULL); // NULL = print to stderr
133}
134#endif
⚠️‼️ Error and/or exit() when things go bad.
🗃️ Lock-Free Unified Memory Buffer Pool with Lazy Allocation
🔍 Memory debugging helpers for tracking allocations in debug builds
void buffer_pool_cleanup_global(void)
void buffer_pool_init_global(void)
asciichat_error_t asciichat_shared_init(const char *default_log_filename, bool is_client)
Initialize common subsystems shared by client and server.
Definition common.c:64
#define FATAL(code,...)
Exit with error code and custom message, with stack trace in debug builds.
Definition common.h:151
void known_hosts_cleanup(void)
Cleanup function to free cached known_hosts path.
void asciichat_errno_cleanup(void)
Cleanup error system resources.
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:46
@ ERROR_PLATFORM_INIT
Definition error_codes.h:57
@ ASCIICHAT_OK
Definition error_codes.h:48
@ ERROR_CONFIG
Definition error_codes.h:54
int g_max_fps
Runtime configurable maximum frame rate (can be overridden via environment or command line)
Definition common.c:30
void log_truncate_if_large(void)
Manually truncate large log files.
void log_init(const char *filename, log_level_t level, bool force_stderr, bool use_mmap)
Initialize the logging system.
#define log_file(...)
File-only logging - writes to log file only, no stderr output.
void log_set_terminal_output(bool enabled)
Control stderr output to terminal.
#define GET_OPTION(field)
Safely get a specific option field (lock-free read)
Definition options.h:644
const options_t * options_get(void)
Get current options (lock-free read)
Definition rcu.c:222
int apply_palette_config(palette_type_t type, const char *custom_chars)
Apply palette configuration (set global palette)
Definition palette.c:277
void platform_cleanup(void)
Cleanup platform-specific subsystems.
#define UNUSED(x)
Suppress unused parameter warnings.
asciichat_error_t platform_init(void)
Initialize platform-specific subsystems.
bool(* shutdown_check_fn)(void)
Shutdown check callback function type.
Definition shutdown.h:32
bool shutdown_is_requested(void)
Check if shutdown has been requested.
Definition common.c:45
void shutdown_register_callback(shutdown_check_fn callback)
Register application's shutdown check function.
Platform initialization and static synchronization helpers.
Known hosts management for MITM attack prevention.
Application limits and constraints.
📝 Logging API with multiple log levels and terminal output control
⚙️ Command-line options parsing and configuration management for ascii-chat
ASCII Palette Management for Video-to-ASCII Conversion.
Cross-platform memory management utilities.
void options_state_shutdown(void)
Shutdown RCU options system.
Definition rcu.c:197
Consolidated options structure.
Definition options.h:439
char palette_custom[256]
Custom palette characters.
Definition options.h:582
bool palette_custom_set
True if custom palette was set.
Definition options.h:583
char log_file[256]
Log file path.
Definition options.h:535
Cross-platform system functions interface for ascii-chat.
Common SIMD utilities and structures.