Called from a log hook — appends a line to the ring buffer (thread-safe) */
| 390 | |
| 391 | /* Called from a log hook — appends a line to the ring buffer (thread-safe) */ |
| 392 | void cbm_ui_log_append(const char *line) { |
| 393 | if (!line) |
| 394 | return; |
| 395 | /* Ensure mutex is initialized (safe for early single-threaded logging |
| 396 | * and concurrent calls via atomic_exchange once-init pattern). */ |
| 397 | cbm_ui_log_init(); |
| 398 | cbm_mutex_lock(&g_log_mutex); |
| 399 | snprintf(g_log_ring[g_log_head], LOG_LINE_MAX, "%s", line); |
| 400 | g_log_head = (g_log_head + 1) % LOG_RING_SIZE; |
| 401 | if (g_log_count < LOG_RING_SIZE) |
| 402 | g_log_count++; |
| 403 | cbm_mutex_unlock(&g_log_mutex); |
| 404 | } |
| 405 | |
| 406 | /* Append a printf-formatted fragment at *pos within a bufsz buffer, never |
| 407 | * advancing *pos past bufsz. snprintf returns the length it WOULD have written, |
no test coverage detected