|
ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
|
👥 Per-client lifecycle manager: threading coordination, state management, and client lifecycle orchestration More...
Go to the source code of this file.
Data Structures | |
| struct | client_dispatch_entry_t |
| Hash table entry for client packet dispatch. More... | |
Macros | |
| #define | DEBUG_NETWORK 1 |
| #define | DEBUG_THREADS 1 |
| #define | DEBUG_MEMORY 1 |
| #define | CLIENT_DISPATCH_HASH_SIZE 32 |
| #define | CLIENT_DISPATCH_HANDLER_COUNT 12 |
| #define | CLIENT_DISPATCH_HASH(type) ((type) % CLIENT_DISPATCH_HASH_SIZE) |
| #define | MAX_AUDIO_BATCH 8 |
Typedefs | |
| typedef void(* | client_packet_handler_t) (client_info_t *client, const void *data, size_t len) |
Functions | |
| void * | client_send_thread_func (void *arg) |
| Client packet send thread. | |
| void * | client_dispatch_thread (void *arg) |
| Async dispatch thread for WebRTC clients. | |
| void | broadcast_server_state_to_all_clients (void) |
| Notify all clients of state changes. | |
| client_info_t * | find_client_by_id (uint32_t client_id) |
| Fast O(1) client lookup by ID using hash table. | |
| client_info_t * | find_client_by_socket (socket_t socket) |
| Find client by socket descriptor using linear search. | |
| int | add_client (server_context_t *server_ctx, socket_t socket, const char *client_ip, int port) |
| int | add_webrtc_client (server_context_t *server_ctx, acip_transport_t *transport, const char *client_ip, bool start_threads) |
| Register a WebRTC client with the server. | |
| int | remove_client (server_context_t *server_ctx, uint32_t client_id) |
| void * | client_receive_thread (void *arg) |
| int | start_webrtc_client_threads (server_context_t *server_ctx, uint32_t client_id) |
| Start threads for a WebRTC client after crypto initialization. | |
| void | stop_client_threads (client_info_t *client) |
| void | cleanup_client_media_buffers (client_info_t *client) |
| void | cleanup_client_packet_queues (client_info_t *client) |
| int | process_encrypted_packet (client_info_t *client, packet_type_t *type, void **data, size_t *len, uint32_t *sender_id) |
| void | process_decrypted_packet (client_info_t *client, packet_type_t type, void *data, size_t len) |
Variables | |
| client_manager_t | g_client_manager |
| Global client manager singleton - central coordination point. | |
| rwlock_t | g_client_manager_rwlock = {0} |
| Reader-writer lock protecting the global client manager. | |
👥 Per-client lifecycle manager: threading coordination, state management, and client lifecycle orchestration
Each connected client spawns multiple dedicated threads:
This per-client threading model provides several advantages:
The module manages two primary data structures:
LOCK ORDERING PROTOCOL (prevents deadlocks):
SNAPSHOT PATTERN (reduces lock contention):
Thread creation order (in add_client()):
Thread termination order (in remove_client()):
The original server.c contained all client management code inline, making it:
This modular approach provides:
Definition in file src/server/client.c.
| #define CLIENT_DISPATCH_HANDLER_COUNT 12 |
Definition at line 161 of file src/server/client.c.
| #define CLIENT_DISPATCH_HASH | ( | type | ) | ((type) % CLIENT_DISPATCH_HASH_SIZE) |
Definition at line 171 of file src/server/client.c.
| #define CLIENT_DISPATCH_HASH_SIZE 32 |
Definition at line 160 of file src/server/client.c.
| #define DEBUG_MEMORY 1 |
Definition at line 152 of file src/server/client.c.
| #define DEBUG_NETWORK 1 |
Definition at line 150 of file src/server/client.c.
| #define DEBUG_THREADS 1 |
Definition at line 151 of file src/server/client.c.
| #define MAX_AUDIO_BATCH 8 |
| typedef void(* client_packet_handler_t) (client_info_t *client, const void *data, size_t len) |
Definition at line 158 of file src/server/client.c.
| int add_client | ( | server_context_t * | server_ctx, |
| socket_t | socket, | ||
| const char * | client_ip, | ||
| int | port | ||
| ) |
Definition at line 534 of file src/server/client.c.
References acip_tcp_transport_create(), audio_ring_buffer_create_for_capture(), audio_ring_buffer_destroy(), broadcast_server_state_to_all_clients(), buffer_pool_free(), client_manager_t::client_count, client_manager_t::clients, client_manager_t::clients_by_id, crypto_handshake_is_ready(), crypto_server_get_context(), g_audio_mixer, g_client_manager, g_client_manager_rwlock, handle_client_capabilities_packet(), mixer_add_source(), mutex_init(), network_error_string(), client_manager_t::next_client_id, packet_queue_create_with_pools(), packet_queue_destroy(), receive_packet_secure(), remove_client(), safe_snprintf(), server_crypto_handshake(), server_crypto_init(), server_context_t::session_host, session_host_add_client(), set_socket_timeout(), server_context_t::tcp_server, tcp_server_add_client(), video_frame_buffer_create(), and video_frame_buffer_destroy().
| int add_webrtc_client | ( | server_context_t * | server_ctx, |
| acip_transport_t * | transport, | ||
| const char * | client_ip, | ||
| bool | start_threads | ||
| ) |
Register a WebRTC client with the server.
Registers a client that connected via WebRTC data channel instead of TCP socket. This function reuses most of add_client() logic but skips:
DIFFERENCES FROM add_client():
| server_ctx | Server context |
| transport | WebRTC transport (already created and connected) |
| client_ip | Client IP address for logging (may be empty for P2P) |
Definition at line 887 of file src/server/client.c.
References acip_send_server_state(), audio_ring_buffer_create_for_capture(), audio_ring_buffer_destroy(), broadcast_server_state_to_all_clients(), client_manager_t::client_count, client_manager_t::clients, client_manager_t::clients_by_id, g_audio_mixer, g_client_manager, g_client_manager_rwlock, mixer_add_source(), mutex_init(), client_manager_t::next_client_id, packet_queue_create_with_pools(), remove_client(), safe_snprintf(), send_server_state_to_client(), server_context_t::session_host, session_host_add_client(), video_frame_buffer_create(), and video_frame_buffer_destroy().
| void broadcast_server_state_to_all_clients | ( | void | ) |
Notify all clients of state changes.
Definition at line 2258 of file src/server/client.c.
References acip_send_server_state(), client_manager_t::client_count, client_manager_t::clients, crypto_handshake_get_context(), find_client_by_id(), format_duration_ns(), g_client_manager, g_client_manager_rwlock, time_elapsed_ns(), and time_get_ns().
Referenced by add_client(), add_webrtc_client(), and remove_client().
| void cleanup_client_media_buffers | ( | client_info_t * | client | ) |
Definition at line 2438 of file src/server/client.c.
References audio_ring_buffer_destroy(), opus_codec_destroy(), and video_frame_buffer_destroy().
| void cleanup_client_packet_queues | ( | client_info_t * | client | ) |
Definition at line 2474 of file src/server/client.c.
References packet_queue_destroy().
| void * client_dispatch_thread | ( | void * | arg | ) |
Async dispatch thread for WebRTC clients.
Async dispatch thread - processes queued received packets.
Decouples receive from dispatch to prevent backpressure on the network socket. Received packets are queued by the receive thread, and processed asynchronously here. This allows the receive thread to keep accepting packets while dispatch processes them.
Definition at line 1449 of file src/server/client.c.
References acip_handle_server_packet(), crypto_decrypt(), crypto_result_to_string(), g_server_should_exit, packet_queue_free_packet(), packet_queue_try_dequeue(), and time_get_ns().
| void * client_receive_thread | ( | void * | arg | ) |
Definition at line 1582 of file src/server/client.c.
References acip_server_receive_and_dispatch(), asciichat_errno_destroy(), asciichat_thread_self(), buffer_pool_free(), g_server_should_exit, packet_queue_enqueue(), platform_sleep_ms(), and remove_client().
| void * client_send_thread_func | ( | void * | arg | ) |
Client packet send thread.
Definition at line 1775 of file src/server/client.c.
References acip_send_ascii_frame(), acip_send_audio_batch(), acip_send_audio_opus_batch(), acip_send_clear_console(), asciichat_errno_destroy(), crypto_handshake_is_ready(), crypto_handshake_rekey_request(), crypto_handshake_should_rekey(), g_server_should_exit, MAX_AUDIO_BATCH, packet_queue_free_packet(), packet_queue_try_dequeue(), packet_send_via_transport(), platform_sleep_us(), time_elapsed_ns(), time_get_ns(), and video_frame_get_latest().
| client_info_t * find_client_by_id | ( | uint32_t | client_id | ) |
Fast O(1) client lookup by ID using hash table.
This is the primary method for locating clients throughout the server. It uses a hash table for constant-time lookups regardless of client count, making it suitable for high-performance operations like rendering and stats.
PERFORMANCE CHARACTERISTICS:
USAGE PATTERNS:
| client_id | Unique identifier for the client (0 is invalid) |
Definition at line 308 of file src/server/client.c.
References client_manager_t::clients_by_id, g_client_manager, and g_client_manager_rwlock.
Referenced by broadcast_server_state_to_all_clients(), crypto_server_cleanup_client(), crypto_server_decrypt_packet(), crypto_server_encrypt_packet(), crypto_server_get_context(), crypto_server_is_ready(), and start_webrtc_client_threads().
| client_info_t * find_client_by_socket | ( | socket_t | socket | ) |
Find client by socket descriptor using linear search.
This function provides socket-based client lookup, primarily used during connection establishment before client IDs are assigned. Less efficient than find_client_by_id() but necessary for socket-based operations.
PERFORMANCE CHARACTERISTICS:
USAGE PATTERNS:
| socket | Platform-abstracted socket descriptor to search for |
Definition at line 353 of file src/server/client.c.
References client_manager_t::clients, g_client_manager, and g_client_manager_rwlock.
| void process_decrypted_packet | ( | client_info_t * | client, |
| packet_type_t | type, | ||
| void * | data, | ||
| size_t | len | ||
| ) |
Process a decrypted packet from a client
| client | Client info structure |
| type | Packet type |
| data | Packet data |
| len | Packet length |
Definition at line 3136 of file src/server/client.c.
References check_and_record_packet_rate_limit(), disconnect_client_for_bad_data(), and g_rate_limiter.
| int process_encrypted_packet | ( | client_info_t * | client, |
| packet_type_t * | type, | ||
| void ** | data, | ||
| size_t * | len, | ||
| uint32_t * | sender_id | ||
| ) |
Process an encrypted packet from a client
| client | Client info structure |
| type | Pointer to packet type (will be updated with decrypted type) |
| data | Pointer to packet data (will be updated with decrypted data) |
| len | Pointer to packet length (will be updated with decrypted length) |
| sender_id | Pointer to sender ID (will be updated with decrypted sender ID) |
Definition at line 2516 of file src/server/client.c.
References buffer_pool_alloc(), buffer_pool_free(), crypto_server_decrypt_packet(), and crypto_server_is_ready().
| int remove_client | ( | server_context_t * | server_ctx, |
| uint32_t | client_id | ||
| ) |
Definition at line 1152 of file src/server/client.c.
References acip_transport_destroy(), asciichat_thread_equal(), asciichat_thread_join(), asciichat_thread_self(), broadcast_server_state_to_all_clients(), client_manager_t::client_count, client_manager_t::clients, client_manager_t::clients_by_id, crypto_handshake_destroy(), g_audio_mixer, g_client_manager, g_client_manager_rwlock, mixer_remove_source(), mutex_destroy(), packet_queue_stop(), platform_sleep_us(), server_context_t::session_host, session_host_remove_client(), server_context_t::tcp_server, and tcp_server_stop_client_threads().
Referenced by add_client(), add_webrtc_client(), client_receive_thread(), and server_main().
| int start_webrtc_client_threads | ( | server_context_t * | server_ctx, |
| uint32_t | client_id | ||
| ) |
Start threads for a WebRTC client after crypto initialization.
This is called by WebSocket handler after crypto handshake is initialized. It ensures receive thread doesn't try to process packets before crypto context exists.
| server_ctx | Server context |
| client_id | Client ID to start threads for |
Definition at line 2397 of file src/server/client.c.
References find_client_by_id().
| void stop_client_threads | ( | client_info_t * | client | ) |
Definition at line 2413 of file src/server/client.c.
References asciichat_thread_join().
| client_manager_t g_client_manager |
Global client manager singleton - central coordination point.
Global client manager.
This is the primary data structure for managing all connected clients. It serves as the bridge between main.c's connection accept loop and the per-client threading architecture.
STRUCTURE COMPONENTS:
THREAD SAFETY: Protected by g_client_manager_rwlock for concurrent access
Definition at line 255 of file src/server/client.c.
Referenced by add_client(), add_webrtc_client(), any_clients_sending_video(), broadcast_server_state_to_all_clients(), find_client_by_id(), find_client_by_socket(), remove_client(), send_server_state_to_client(), server_main(), stats_logger_thread(), and update_server_stats().
| rwlock_t g_client_manager_rwlock = {0} |
Reader-writer lock protecting the global client manager.
Read-write lock protecting client manager.
This lock enables high-performance concurrent access patterns:
USAGE PATTERN:
Definition at line 270 of file src/server/client.c.
Referenced by add_client(), add_webrtc_client(), broadcast_server_state_to_all_clients(), find_client_by_id(), find_client_by_socket(), remove_client(), server_main(), stats_logger_thread(), and update_server_stats().