ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
session_log_buffer.h File Reference

Thread-safe circular log buffer for session screens (status, splash). More...

Go to the source code of this file.

Data Structures

struct  session_log_entry_t
 One formatted session log line and its monotonic history sequence. More...

Macros

#define SESSION_LOG_BUFFER_SIZE   16384
#define SESSION_LOG_LINE_MAX   1024

Functions

session_log_buffer_t * session_log_buffer_create (void)
 Create a new session log buffer instance.
void session_log_buffer_destroy (session_log_buffer_t *buf)
 Cleanup session log buffer instance.
void session_log_buffer_clear (session_log_buffer_t *buf)
 Clear all log entries from buffer.
void session_log_buffer_append (session_log_buffer_t *buf, const char *message)
 Append a log message to the buffer.
size_t session_log_buffer_get_recent (session_log_buffer_t *buf, session_log_entry_t *out_entries, size_t max_count)
 Get recent log entries from buffer.

Detailed Description

Thread-safe circular log buffer for session screens (status, splash).

Provides a reusable log capture mechanism for session screens that need to display logs alongside fixed header content without terminal scrolling.

Thread-safe for concurrent append operations. Designed for use by:

  • Server status screen (live log feed under status header)
  • Splash screen (logs under animated ASCII art)
Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
February 2026

Definition in file session_log_buffer.h.

Macro Definition Documentation

◆ SESSION_LOG_BUFFER_SIZE

◆ SESSION_LOG_LINE_MAX

#define SESSION_LOG_LINE_MAX   1024

Definition at line 31 of file session_log_buffer.h.

Referenced by log_search_filter_buffer(), and session_log_buffer_append().

Function Documentation

◆ session_log_buffer_append()

void session_log_buffer_append ( session_log_buffer_t * buf,
const char * message )

Append a log message to the buffer.

Thread-safe. Called from logging system to capture messages. Message is copied into circular buffer (oldest entry overwritten if full).

Parameters
bufBuffer instance (must not be NULL)
messageLog message text (already formatted with colors)

Definition at line 73 of file session_log_buffer.c.

73 {
74 if (!buf || !message) {
75 // Fail silently - this is called FROM the logging system
76 // Using SET_ERRNO here would cause infinite recursion
77 return;
78 }
79
80 mutex_lock(&buf->mutex);
81
82 // Keep every line of multiline notices and split long lines at UTF-8 boundaries.
83 // Hold the lock for the entire message so concurrent producers cannot interleave it.
84 do {
85 const char *newline = strchr(message, '\n');
86 size_t length = newline ? (size_t)(newline - message) : strlen(message);
87 if (length >= SESSION_LOG_LINE_MAX) {
88 length = SESSION_LOG_LINE_MAX - 1;
89 while (length && ((unsigned char)message[length] & 0xc0) == 0x80)
90 --length;
91 if (!length)
92 length = SESSION_LOG_LINE_MAX - 1; // Malformed UTF-8 must still make progress.
93 }
94 size_t pos = atomic_load_u64(&buf->write_pos);
95 memcpy(buf->entries[pos].message, message, length);
96 buf->entries[pos].message[length] = '\0';
97 buf->entries[pos].sequence = atomic_fetch_add_u64(&buf->sequence, 1) + 1;
98 atomic_store_u64(&buf->write_pos, (pos + 1) % SESSION_LOG_BUFFER_SIZE);
99 message += length;
100 if (*message == '\n')
101 ++message;
102 } while (*message);
103
104 mutex_unlock(&buf->mutex);
105}
#define SESSION_LOG_BUFFER_SIZE
#define SESSION_LOG_LINE_MAX
session_log_entry_t entries[SESSION_LOG_BUFFER_SIZE]
char message[1024]
Formatted log message (may include ANSI colors).
uint64_t sequence
Sequence number (monotonic, for ordering).

References session_log_buffer::entries, session_log_entry_t::message, session_log_buffer::mutex, session_log_buffer::sequence, session_log_entry_t::sequence, SESSION_LOG_BUFFER_SIZE, SESSION_LOG_LINE_MAX, and session_log_buffer::write_pos.

Referenced by log_file_msg(), log_msg(), log_plain_msg(), and ui_session_log().

◆ session_log_buffer_clear()

void session_log_buffer_clear ( session_log_buffer_t * buf)

Clear all log entries from buffer.

Thread-safe. Resets buffer to empty state, discarding all captured logs. Useful for clearing initialization logs before screen starts rendering.

Parameters
bufBuffer instance (must not be NULL)

Definition at line 53 of file session_log_buffer.c.

53 {
54 if (!buf) {
55 return;
56 }
57
58 mutex_lock(&buf->mutex);
59
60 // Reset write position and sequence
61 atomic_store_u64(&buf->write_pos, 0);
62 atomic_store_u64(&buf->sequence, 0);
63
64 // Clear all entries
65 for (size_t i = 0; i < SESSION_LOG_BUFFER_SIZE; i++) {
66 buf->entries[i].message[0] = '\0';
67 buf->entries[i].sequence = 0;
68 }
69
70 mutex_unlock(&buf->mutex);
71}

References session_log_buffer::entries, session_log_entry_t::message, session_log_buffer::mutex, session_log_buffer::sequence, session_log_entry_t::sequence, SESSION_LOG_BUFFER_SIZE, and session_log_buffer::write_pos.

Referenced by terminal_screen_log_clear().

◆ session_log_buffer_create()

session_log_buffer_t * session_log_buffer_create ( void )

Create a new session log buffer instance.

Allocates and initializes a circular buffer for log capture. Caller is responsible for calling session_log_buffer_destroy() when done.

Returns
Pointer to new buffer instance, or NULL on allocation failure

Definition at line 31 of file session_log_buffer.c.

31 {
33 if (!buf) {
34 return NULL;
35 }
36
37 atomic_store_u64(&buf->write_pos, 0);
38 atomic_store_u64(&buf->sequence, 0);
39 mutex_init(&buf->mutex, "log_buffer");
40
41 return buf;
42}
#define SAFE_CALLOC(count, size, cast)
Definition common.h:275
struct session_log_buffer session_log_buffer_t
Thread-safe fixed-size history ring for session-screen log lines.

References session_log_buffer::mutex, SAFE_CALLOC, session_log_buffer::sequence, and session_log_buffer::write_pos.

Referenced by log_init(), terminal_screen_log_init(), and ui_session_create().

◆ session_log_buffer_destroy()

void session_log_buffer_destroy ( session_log_buffer_t * buf)

Cleanup session log buffer instance.

Frees the buffer and all internal resources. Safe to call with NULL.

Parameters
bufBuffer instance to destroy (can be NULL)

Definition at line 44 of file session_log_buffer.c.

44 {
45 if (!buf) {
46 return;
47 }
48
49 mutex_destroy(&buf->mutex);
50 SAFE_FREE(buf);
51}
#define SAFE_FREE(ptr)
Definition common.h:377

References session_log_buffer::mutex, and SAFE_FREE.

Referenced by log_system_destroy(), terminal_screen_log_destroy(), and ui_session_destroy().

◆ session_log_buffer_get_recent()

size_t session_log_buffer_get_recent ( session_log_buffer_t * buf,
session_log_entry_t * out_entries,
size_t max_count )

Get recent log entries from buffer.

Thread-safe. Copies up to max_count recent entries into out_entries. Entries are returned in chronological order (oldest first).

Parameters
bufBuffer instance (must not be NULL)
out_entriesOutput array to fill with log entries
max_countMaximum number of entries to return
Returns
Number of entries actually copied (may be less than max_count)

Definition at line 107 of file session_log_buffer.c.

107 {
108 if (!buf || !out_entries || max_count == 0) {
109 // Fail silently - called from display code that handles 0 gracefully
110 // Using SET_ERRNO here could cause recursion if error logging is enabled
111 return 0;
112 }
113
114 mutex_lock(&buf->mutex);
115
116 size_t write_pos = atomic_load_u64(&buf->write_pos);
117 uint64_t total_entries = atomic_load_u64(&buf->sequence);
118
119 size_t entries_to_check = total_entries < SESSION_LOG_BUFFER_SIZE ? (size_t)total_entries : SESSION_LOG_BUFFER_SIZE;
120 if (entries_to_check > max_count)
121 entries_to_check = max_count;
122 size_t start_pos = (write_pos + SESSION_LOG_BUFFER_SIZE - entries_to_check) % SESSION_LOG_BUFFER_SIZE;
123
124 size_t count = 0;
125 for (size_t i = 0; i < entries_to_check && count < max_count; i++) {
126 size_t idx = (start_pos + i) % SESSION_LOG_BUFFER_SIZE;
127 if (buf->entries[idx].sequence > 0) {
128 memcpy(&out_entries[count], &buf->entries[idx], sizeof(session_log_entry_t));
129 count++;
130 }
131 }
132
133 mutex_unlock(&buf->mutex);
134 return count;
135}
unsigned long long uint64_t
Definition common.h:63
atomic_t write_pos
Definition mmap.c:40
One formatted session log line and its monotonic history sequence.

References session_log_buffer::entries, session_log_buffer::mutex, session_log_buffer::sequence, session_log_entry_t::sequence, SESSION_LOG_BUFFER_SIZE, session_log_buffer::write_pos, and write_pos.

Referenced by log_search_filter_buffer(), and terminal_screen_compose().