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

Thread-safe circular log buffer for session screens. More...

Go to the source code of this file.

Data Structures

struct  session_log_buffer
 Internal circular buffer structure. More...
 

Typedefs

typedef struct session_log_buffer session_log_buffer_t
 Internal circular buffer structure.
 

Functions

bool session_log_buffer_init (void)
 
void session_log_buffer_destroy (void)
 
void session_log_buffer_clear (void)
 
void session_log_buffer_append (const char *message)
 
size_t session_log_buffer_get_recent (session_log_entry_t *out_entries, size_t max_count)
 

Detailed Description

Thread-safe circular log buffer for session screens.

Definition in file session_log_buffer.c.

Typedef Documentation

◆ session_log_buffer_t

Internal circular buffer structure.

Function Documentation

◆ session_log_buffer_append()

void session_log_buffer_append ( const char *  message)

Definition at line 70 of file session_log_buffer.c.

70 {
71 if (!g_log_buffer || !message) {
72 // Fail silently - this is called FROM the logging system
73 // Using SET_ERRNO here would cause infinite recursion
74 return;
75 }
76
77 mutex_lock(&g_log_buffer->mutex);
78
79 size_t pos = atomic_load(&g_log_buffer->write_pos);
80 uint64_t seq = atomic_fetch_add(&g_log_buffer->sequence, 1);
81
82 SAFE_STRNCPY(g_log_buffer->entries[pos].message, message, SESSION_LOG_LINE_MAX);
83 g_log_buffer->entries[pos].sequence = seq;
84
85 atomic_store(&g_log_buffer->write_pos, (pos + 1) % SESSION_LOG_BUFFER_SIZE);
86
87 mutex_unlock(&g_log_buffer->mutex);
88}
session_log_entry_t entries[SESSION_LOG_BUFFER_SIZE]
_Atomic size_t write_pos
_Atomic uint64_t sequence

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

Referenced by server_status_log_append().

◆ session_log_buffer_clear()

void session_log_buffer_clear ( void  )

Definition at line 50 of file session_log_buffer.c.

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

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

Referenced by server_status_log_clear().

◆ session_log_buffer_destroy()

void session_log_buffer_destroy ( void  )

Definition at line 42 of file session_log_buffer.c.

42 {
43 if (!g_log_buffer) {
44 return;
45 }
46 mutex_destroy(&g_log_buffer->mutex);
47 SAFE_FREE(g_log_buffer);
48}
int mutex_destroy(mutex_t *mutex)
Definition threading.c:21

References session_log_buffer::mutex, and mutex_destroy().

Referenced by client_main(), server_status_log_destroy(), and session_client_like_run().

◆ session_log_buffer_get_recent()

size_t session_log_buffer_get_recent ( session_log_entry_t *  out_entries,
size_t  max_count 
)

Definition at line 90 of file session_log_buffer.c.

90 {
91 if (!g_log_buffer || !out_entries || max_count == 0) {
92 // Fail silently - called from display code that handles 0 gracefully
93 // Using SET_ERRNO here could cause recursion if error logging is enabled
94 return 0;
95 }
96
97 mutex_lock(&g_log_buffer->mutex);
98
99 size_t write_pos = atomic_load(&g_log_buffer->write_pos);
100 uint64_t total_entries = atomic_load(&g_log_buffer->sequence);
101
102 size_t start_pos = write_pos;
103 size_t entries_to_check = SESSION_LOG_BUFFER_SIZE;
104
105 if (total_entries < SESSION_LOG_BUFFER_SIZE) {
106 start_pos = 0;
107 entries_to_check = write_pos;
108 }
109
110 size_t count = 0;
111 for (size_t i = 0; i < entries_to_check && count < max_count; i++) {
112 size_t idx = (start_pos + i) % SESSION_LOG_BUFFER_SIZE;
113 if (g_log_buffer->entries[idx].sequence > 0) {
114 memcpy(&out_entries[count], &g_log_buffer->entries[idx], sizeof(session_log_entry_t));
115 count++;
116 }
117 }
118
119 mutex_unlock(&g_log_buffer->mutex);
120 return count;
121}
_Atomic uint64_t write_pos
Definition mmap.c:37

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

Referenced by interactive_grep_gather_and_filter_logs(), and terminal_screen_render().

◆ session_log_buffer_init()

bool session_log_buffer_init ( void  )

Definition at line 25 of file session_log_buffer.c.

25 {
26 if (g_log_buffer) {
27 return true; // Already initialized
28 }
29
30 g_log_buffer = SAFE_CALLOC(1, sizeof(session_log_buffer_t), session_log_buffer_t *);
31 if (!g_log_buffer) {
32 return false;
33 }
34
35 atomic_init(&g_log_buffer->write_pos, 0);
36 atomic_init(&g_log_buffer->sequence, 0);
37 mutex_init(&g_log_buffer->mutex);
38
39 return true;
40}
Internal circular buffer structure.
int mutex_init(mutex_t *mutex)
Definition threading.c:16

References session_log_buffer::mutex, mutex_init(), session_log_buffer::sequence, and session_log_buffer::write_pos.

Referenced by server_status_log_init(), and splash_intro_start().