ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
common.c File Reference

🔧 Core utilities: memory management, safe macros, and cross-platform helpers More...

Go to the source code of this file.

Functions

bool shutdown_is_requested (void)
 
 __attribute__ ((constructor))
 Register fork handlers for common module.
 
asciichat_error_t asciichat_shared_init (const char *log_file, bool is_client)
 
void asciichat_shared_destroy (void)
 Clean up all shared library subsystems.
 

Variables

ASCIICHAT_API int g_argc = 0
 
ASCIICHAT_API char ** g_argv = NULL
 
ASCIICHAT_API bool g_color_flag_passed = false
 
ASCIICHAT_API bool g_color_flag_value = false
 

Detailed Description

🔧 Core utilities: memory management, safe macros, and cross-platform helpers

Definition in file common.c.

Function Documentation

◆ __attribute__()

__attribute__ ( (constructor)  )

Register fork handlers for common module.

Definition at line 104 of file common.c.

104 {
105 pthread_atfork(NULL, NULL, asciichat_common_atfork_child);
106}

◆ asciichat_shared_destroy()

void asciichat_shared_destroy ( void  )

Clean up all shared library subsystems.

Performs comprehensive cleanup of all subsystems initialized by asciichat_shared_init(). All cleanup functions are idempotent (safe to call multiple times), so this can be called explicitly and also via atexit() without issues.

Cleanup order is carefully chosen to be the reverse of initialization, ensuring dependencies are respected (e.g., timer cleanup before memory reporting, memory reporting before errno cleanup).

Note
This function is safe to call even if init failed or wasn't called.
All subsystem cleanup functions must remain idempotent.

Definition at line 164 of file common.c.

164 {
165 // Guard against double cleanup (can be called explicitly + via atexit)
166 static bool shutdown_done = false;
167 if (shutdown_done) {
168 return;
169 }
170 shutdown_done = true;
171
172 // Cleanup in reverse order of initialization (LIFO)
173 // This ensures dependencies are properly handled
174
175 // 0. Stop background threads first (before any cleanup that might use them)
176 // Terminal resize detection thread (Windows only, checks if active)
177 extern void terminal_stop_resize_detection(void);
178 terminal_stop_resize_detection();
179
180#ifndef NDEBUG
181 // Lock debug thread - must join before any lock cleanup
182 extern void lock_debug_cleanup_thread(void);
184
185 // Lock debug system - set initialized=false so mutex_lock uses mutex_lock_impl directly
186 // This must happen after thread cleanup but before any subsystem that uses mutex_lock
187 extern void lock_debug_destroy(void);
189#endif
190
191 // 1. Webcam - cleanup resources
193
194 // 2. SIMD caches - cleanup CPU-specific caches
196
197 // 3. Discovery service strings cache - cleanup session string cache
199
200 // 4. Logging - in correct order (end first, then begin)
203
204 // 5. Known hosts - cleanup authentication state
206
207 // 6. Options state - cleanup RCU-based options
209
210 // 7. Buffer pool - cleanup global buffer pool
212
213 // 8. Platform cleanup - restores terminal, cleans up platform resources
214 // (includes symbol cache cleanup on Windows)
216
217 // 9. Keyboard - restore terminal settings (redundant with platform_destroy but safe)
218 extern void keyboard_destroy(void);
219 keyboard_destroy();
220
221 // 10. Timer system - cleanup timers (may still log!)
223
224 // 11. Error context cleanup
226
227 // 12. Logging cleanup - free log format buffers before memory report
228 log_destroy();
229
230 // 13. Memory stats (debug builds only) - runs with colors still available
231 // Note: PCRE2 singletons are ignored in the report (expected system allocations)
232 // Note: debug_memory_report() is also called manually during shutdown in server_main()
233 // The function is safe to call multiple times with polling-based locking
234#if defined(USE_MIMALLOC_DEBUG) && !defined(NDEBUG)
235 print_mimalloc_stats();
236#endif
237
238#if defined(DEBUG_MEMORY) && !defined(NDEBUG)
239 debug_memory_report();
240#endif
241
242 // 14. Color cleanup - free compiled ANSI strings (AFTER memory report)
245
246 // 15. PCRE2 - cleanup all regex singletons together
248}
void asciichat_errno_destroy(void)
void buffer_pool_cleanup_global(void)
void colorscheme_destroy(void)
void acds_strings_destroy(void)
Cleanup function for session string cache Called by asciichat_shared_destroy() during library cleanup...
void platform_destroy(void)
Definition init.c:15
void known_hosts_destroy(void)
void lock_debug_cleanup_thread(void)
Definition lock.c:1371
void lock_debug_destroy(void)
Definition lock.c:1370
void log_shutdown_end(void)
void log_destroy(void)
void log_cleanup_colors(void)
Clean up compiled color scheme.
void log_shutdown_begin(void)
void asciichat_pcre2_cleanup_all(void)
Free all PCRE2 singletons in the global registry.
Definition pcre2.c:197
void options_state_destroy(void)
Definition rcu.c:309
void timer_system_destroy(void)
Definition util/time.c:146
void simd_caches_destroy_all(void)
void webcam_destroy(void)

References acds_strings_destroy(), asciichat_errno_destroy(), asciichat_pcre2_cleanup_all(), buffer_pool_cleanup_global(), colorscheme_destroy(), known_hosts_destroy(), lock_debug_cleanup_thread(), lock_debug_destroy(), log_cleanup_colors(), log_destroy(), log_shutdown_begin(), log_shutdown_end(), options_state_destroy(), platform_destroy(), simd_caches_destroy_all(), timer_system_destroy(), and webcam_destroy().

Referenced by client_main(), and main().

◆ asciichat_shared_init()

asciichat_error_t asciichat_shared_init ( const char *  log_file,
bool  is_client 
)

Definition at line 109 of file common.c.

109 {
110 // Initialize shared subsystems BEFORE options_init()
111 // This allows options_init() to use properly configured logging with colors
112 //
113 // NOTE: This function is called BEFORE options_init(), so we can't use GET_OPTION()
114 // Palette config and quiet mode will be applied after options_init() is called
115
116 // Only register initialization tracking once
117 if (!g_shared_initialized) {
118 // 1. TIMER SYSTEM - Initialize first so timing is available for everything else
119 if (!timer_system_init()) {
120 FATAL(ERROR_PLATFORM_INIT, "Failed to initialize timer system");
121 }
122
123 // 2. LOGGING - Initialize with provided log file
124 // Force stderr for client-like modes when stdout is piped to keep stdout clean
125 bool force_stderr = is_client && terminal_is_piped_output();
126 // Use LOG_DEBUG by default; will be reconfigured after options_init()
127 log_init(log_file, LOG_DEBUG, force_stderr, false /* don't use_mmap */);
128
129 // 3. PLATFORM - Initialize platform-specific functionality (Winsock, etc)
130 if (platform_init() != ASCIICHAT_OK) {
131 FATAL(ERROR_PLATFORM_INIT, "Failed to initialize platform");
132 }
133
134 // 4. BUFFER POOL - Initialize global shared buffer pool
136
137 // Mark that we've initialized (prevents re-registration of subsystems)
138 g_shared_initialized = true;
139 }
140
141 // NOTE: This library function does NOT register atexit() handlers.
142 // Library code should not own the process lifecycle. The application
143 // is responsible for calling atexit(asciichat_shared_destroy) if it
144 // wants automatic cleanup on normal exit.
145
146 return ASCIICHAT_OK;
147}
void buffer_pool_init_global(void)
asciichat_error_t platform_init(void)
Definition init.c:10
void log_init(const char *filename, log_level_t level, bool force_stderr, bool use_mmap)
bool terminal_is_piped_output(void)
bool timer_system_init(void)
Definition util/time.c:125

References buffer_pool_init_global(), log_init(), platform_init(), terminal_is_piped_output(), and timer_system_init().

Referenced by main().

◆ shutdown_is_requested()

bool shutdown_is_requested ( void  )

Definition at line 65 of file common.c.

65 {
66 shutdown_check_fn callback = atomic_load(&g_shutdown_callback);
67 if (callback == NULL) {
68 return false; // No callback registered, assume not shutting down
69 }
70 return callback();
71}

Referenced by log_plain_msg(), log_plain_stderr_msg(), and log_plain_stderr_nonewline_msg().

Variable Documentation

◆ g_argc

ASCIICHAT_API int g_argc = 0

Definition at line 45 of file common.c.

Referenced by main(), and terminal_should_color_output().

◆ g_argv

ASCIICHAT_API char** g_argv = NULL

Definition at line 46 of file common.c.

Referenced by main(), and terminal_should_color_output().

◆ g_color_flag_passed

ASCIICHAT_API bool g_color_flag_passed = false

Definition at line 49 of file common.c.

Referenced by colored_string(), log_msg(), and main().

◆ g_color_flag_value

ASCIICHAT_API bool g_color_flag_value = false

Definition at line 50 of file common.c.

Referenced by colored_string(), log_msg(), and main().