ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
Debug_named

Files

file  named.c
 Named object registry for debugging.
 
file  named.h
 Named object registry for debugging — log identifiable resource names.
 

Macros

#define NAMED_REGISTER(ptr, name, type, fmt, parent_ptr)    named_register((uintptr_t)(const void *)(ptr), (name), (type), (fmt), __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register any pointer with base name, type, format spec, and location (auto-suffix)
 
#define NAMED_REGISTER_FMT(ptr, type, fmt_spec, fmt, ...)
 Register with a formatted name, type, and format spec.
 
#define NAMED_UNREGISTER(ptr)   named_unregister((uintptr_t)(const void *)(ptr))
 Unregister a pointer.
 
#define NAMED_GET(ptr)   named_get((uintptr_t)(const void *)(ptr))
 Look up registered name for a pointer.
 
#define NAMED_DESCRIBE(ptr, hint)   named_describe((uintptr_t)(const void *)(ptr), (hint))
 Describe a pointer in log format.
 
#define NAMED_REGISTER_ID(id, name, type, fmt, parent_ptr)    named_register((uintptr_t)(intptr_t)(id), (name), (type), (fmt), __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an integer handle (fd, socket, etc.) with type.
 
#define NAMED_UNREGISTER_ID(id)   named_unregister((uintptr_t)(intptr_t)(id))
 Unregister an integer handle.
 
#define NAMED_DESCRIBE_ID(id, hint)   named_describe((uintptr_t)(intptr_t)(id), (hint))
 Describe an integer handle in log format.
 
#define NAMED_REGISTER_MUTEX(mutex, name, parent_ptr)    named_register((uintptr_t)(const void *)(mutex), (name), "mutex", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a mutex with automatic format specifier.
 
#define NAMED_REGISTER_RWLOCK(lock, name, parent_ptr)    named_register((uintptr_t)(const void *)(lock), (name), "rwlock", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an rwlock with automatic format specifier.
 
#define NAMED_REGISTER_COND(cond, name, parent_ptr)    named_register((uintptr_t)(const void *)(cond), (name), "cond", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a condition variable with automatic format specifier.
 
#define NAMED_REGISTER_SOCKET(socket, name, parent_ptr)    named_register((uintptr_t)(intptr_t)(socket), (name), "socket", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a socket with automatic format specifier.
 
#define NAMED_UNREGISTER_SOCKET(socket)   NAMED_UNREGISTER_ID((socket))
 
#define NAMED_REGISTER_WEBSOCKET(websocket, name, parent_ptr)    named_register((uintptr_t)(const void *)(websocket), (name), "websocket", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a WebSocket connection with automatic format specifier.
 
#define NAMED_REGISTER_DATACHANNEL(datachannel, name, parent_ptr)    named_register((uintptr_t)(const void *)(datachannel), (name), "datachannel", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a data channel with automatic format specifier.
 
#define NAMED_REGISTER_THREADPOOL_WORK(work, name, parent_ptr)    named_register((uintptr_t)(const void *)(work), (name), "work", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a thread pool work item with automatic format specifier.
 
#define NAMED_REGISTER_CLIENT(client, name, parent_ptr)    named_register((uintptr_t)(const void *)(client), (name), "client", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a client connection with automatic format specifier.
 
#define NAMED_REGISTER_CRYPTO_CONTEXT(ctx, name, parent_ptr)    named_register((uintptr_t)(const void *)(ctx), (name), "crypto", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a crypto context with automatic format specifier.
 
#define NAMED_REGISTER_TRANSPORT(transport, name, parent_ptr)    named_register((uintptr_t)(const void *)(transport), (name), "transport", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a transport with automatic format specifier.
 
#define NAMED_REGISTER_FRAME_BUFFER(buf, name, parent_ptr)    named_register((uintptr_t)(const void *)(buf), (name), "frame_buffer", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a frame buffer with automatic format specifier.
 
#define NAMED_REGISTER_PACKET_QUEUE(queue, name, parent_ptr)    named_register((uintptr_t)(const void *)(queue), (name), "packet_queue", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a packet queue with automatic format specifier.
 
#define NAMED_REGISTER_AUDIO_RINGBUF(buf, name, parent_ptr)    named_register((uintptr_t)(const void *)(buf), (name), "audio_ringbuf", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an audio ring buffer with automatic format specifier.
 
#define NAMED_REGISTER_MIXER(mixer, name, parent_ptr)    named_register((uintptr_t)(const void *)(mixer), (name), "mixer", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an audio mixer with automatic format specifier.
 
#define NAMED_REGISTER_AUDIO_CODEC(codec, name, parent_ptr)    named_register((uintptr_t)(const void *)(codec), (name), "audio_codec", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an audio codec with automatic format specifier.
 
#define NAMED_REGISTER_VIDEO_ENCODER(encoder, name, parent_ptr)    named_register((uintptr_t)(const void *)(encoder), (name), "video_encoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a video encoder with automatic format specifier.
 
#define NAMED_REGISTER_BUFFER_POOL(pool, name, parent_ptr)    named_register((uintptr_t)(const void *)(pool), (name), "buffer_pool", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a buffer pool with automatic format specifier.
 
#define NAMED_REGISTER_FFMPEG_DECODER(decoder, name, parent_ptr)    named_register((uintptr_t)(const void *)(decoder), (name), "ffmpeg_decoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an FFmpeg decoder with automatic format specifier.
 
#define NAMED_REGISTER_FFMPEG_ENCODER(encoder, name, parent_ptr)    named_register((uintptr_t)(const void *)(encoder), (name), "ffmpeg_encoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an FFmpeg encoder with automatic format specifier.
 
#define NAMED_REGISTER_H265_ENCODER(encoder, name, parent_ptr)    named_register((uintptr_t)(const void *)(encoder), (name), "h265_encoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an H.265 encoder with automatic format specifier.
 
#define NAMED_REGISTER_H265_DECODER(decoder, name, parent_ptr)    named_register((uintptr_t)(const void *)(decoder), (name), "h265_decoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an H.265 decoder with automatic format specifier.
 
#define NAMED_REGISTER_AUDIO_CONTEXT(ctx, name, parent_ptr)    named_register((uintptr_t)(const void *)(ctx), (name), "audio_context", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an audio context with automatic format specifier.
 
#define NAMED_REGISTER_RATE_LIMITER(limiter, name, parent_ptr)    named_register((uintptr_t)(const void *)(limiter), (name), "rate_limiter", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a rate limiter with automatic format specifier.
 
#define NAMED_REGISTER_WAV_WRITER(writer, name, parent_ptr)    named_register((uintptr_t)(const void *)(writer), (name), "wav_writer", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a WAV writer with automatic format specifier.
 
#define NAMED_REGISTER_MEDIA_SOURCE(source, name, parent_ptr)    named_register((uintptr_t)(const void *)(source), (name), "media_source", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a media source with automatic format specifier.
 
#define NAMED_OPEN(pathname, name, flags, ...)
 Open a file and register the file descriptor.
 
#define NAMED_UNREGISTER_FD(fd)   NAMED_UNREGISTER_ID((fd))
 Unregister a file descriptor.
 
#define NAMED_REGISTER_FD(fd, name)   named_register_fd((fd), (name), __FILE__, __LINE__, __func__)
 Register an existing file descriptor.
 
#define NAMED_REGISTER_ATOMIC(a, name, parent_ptr)    named_register((uintptr_t)(const void *)(a), (name), "atomic", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an atomic_t with automatic format specifier.
 
#define NAMED_REGISTER_ATOMIC_PTR(a, name, parent_ptr)    named_register((uintptr_t)(const void *)(a), (name), "atomic_ptr", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an _Atomic(void *) with automatic format specifier.
 
#define NAMED_REGISTER_THREAD(thread, name, parent_ptr)    named_register(asciichat_thread_to_key((thread)), (name), "thread", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a thread handle with name and automatic format specifier.
 
#define NAMED_UNREGISTER_THREAD(thread)   named_unregister(asciichat_thread_to_key((thread)))
 Unregister a thread handle.
 
#define NAMED_REGISTER_TCP_CLIENT(client, name, parent_ptr)    named_register((uintptr_t)(const void *)(client), (name), "tcp_client", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a TCP client with automatic format specifier.
 
#define NAMED_REGISTER_WEBSOCKET_CLIENT(client, name, parent_ptr)    named_register((uintptr_t)(const void *)(client), (name), "websocket_client", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a WebSocket client with automatic format specifier.
 
#define NAMED_REGISTER_APP_CLIENT(client, name, parent_ptr)    named_register((uintptr_t)(const void *)(client), (name), "app_client", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an app client with automatic format specifier.
 
#define NAMED_REGISTER_VIDEO_FRAME_BUFFER(buf, name, parent_ptr)    named_register((uintptr_t)(const void *)(buf), (name), "video_frame_buffer", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a video frame buffer with automatic format specifier.
 
#define NAMED_REGISTER_NODE_POOL(pool, name, parent_ptr)    named_register((uintptr_t)(const void *)(pool), (name), "node_pool", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a node pool with automatic format specifier.
 
#define NAMED_REGISTER_THREAD_POOL(pool, name, parent_ptr)    named_register((uintptr_t)(const void *)(pool), (name), "thread_pool", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a thread pool with automatic format specifier.
 
#define NAMED_REGISTER_OPTIONS_BUILDER(builder, name, parent_ptr)    named_register((uintptr_t)(const void *)(builder), (name), "options_builder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an options builder with automatic format specifier.
 
#define NAMED_REGISTER_SIMPLE_FRAME_SWAP(swap, name, parent_ptr)    named_register((uintptr_t)(const void *)(swap), (name), "simple_frame_swap", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a simple frame swap with automatic format specifier.
 
#define NAMED_REGISTER_CLIENT_AUDIO_PIPELINE(pipeline, name, parent_ptr)
 Register a client audio pipeline with automatic format specifier.
 
#define NAMED_REGISTER_WEBSOCKET_IMPL(data, name, parent_ptr)   ((void)(data), (void)(name), (void)(parent_ptr))
 
#define NAMED_REGISTER_LWS_CONTEXT(context, name, parent_ptr)    named_register((uintptr_t)(const void *)(context), (name), "lws_context", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a libwebsockets context with automatic format specifier.
 
#define NAMED_REGISTER_FFMPEG_CONTEXT(context, name, parent_ptr)    named_register((uintptr_t)(const void *)(context), (name), "ffmpeg_context", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register an FFmpeg decoder context with automatic format specifier.
 
#define NAMED_REGISTER_CONTEXT(context, context_type, name, parent_ptr)    named_register((uintptr_t)(const void *)(context), (name), (context_type), "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))
 Register a generic context with automatic format specifier.
 
#define NAMED_GET_BY_PTR(key, buffer, size)
 Get name of a pointer/key or format as address fallback.
 
#define NAMED_GET_BY_INT(id, buffer, size)
 Get name of an integer ID or format as hex fallback.
 
#define NAMED_GET_BY_STR(str, buffer, size)
 Copy a string to buffer, with bounds checking.
 

Typedefs

typedef void(* named_iter_callback_t) (uintptr_t key, const char *name, void *user_data)
 Callback function for iterating registered entries.
 

Functions

asciichat_error_t named_init (void)
 Initialize the named object registry.
 
void named_destroy (void)
 Destroy the named object registry.
 
const char * named_register (uintptr_t key, const char *base_name, const char *type, const char *format_spec, const char *file, int line, const char *func, uintptr_t parent_key)
 Register a resource with an auto-suffixed name, type, and location info.
 
const char * named_register_fmt (uintptr_t key, const char *type, const char *format_spec, const char *file, int line, const char *func, const char *fmt,...)
 Register a resource with a formatted name, type, and location info (no auto-suffix)
 
void named_unregister (uintptr_t key)
 Unregister a resource by key.
 
const char * named_update_name (uintptr_t key, const char *new_base_name)
 Update the registered name for a resource with a new base name.
 
const char * named_get (uintptr_t key)
 Look up the registered name for a resource.
 
const char * named_get_type (uintptr_t key)
 Look up the registered type for a resource.
 
const char * named_get_format_spec (uintptr_t key)
 Get the format specifier for a registered named object.
 
const char * named_register_fd (int fd, const char *name, const char *file, int line, const char *func)
 Register a file descriptor with namespace encoding.
 
const char * named_get_fd (int fd)
 Look up a registered file descriptor.
 
const char * named_get_fd_format_spec (int fd)
 Get the format specifier for a registered file descriptor.
 
const char * named_register_packet_type (int pkt_type, const char *file, int line, const char *func)
 Register a packet type with namespace encoding.
 
const char * named_get_packet_type (int pkt_type)
 Look up a registered packet type.
 
const char * named_get_packet_type_format_spec (int pkt_type)
 Get the format specifier for a registered packet type.
 
const char * named_get_by_type_and_id (const char *type_name, size_t type_len, int id)
 Look up an integer ID by type name and value.
 
const char * named_describe (uintptr_t key, const char *type_hint)
 Format a description string for logging.
 
uintptr_t asciichat_thread_to_key (asciichat_thread_t thread)
 Convert a thread handle to a registry key.
 
const char * named_describe_thread (void *thread)
 Describe a thread for logging (function wrapper)
 
void named_registry_register_packet_types (void)
 Register all packet types from packet_type_t enum.
 
void named_registry_for_each (named_iter_callback_t callback, void *user_data)
 Iterate through all registered entries.
 

Type-Specific Description Macros

These macros encapsulate the proper casting and type hint for common types. Use these instead of NAMED_DESCRIBE for better readability and consistency.

#define NAME_DESCRIBE_MUTEX(m)   named_describe((uintptr_t)(const void *)(m), "mutex")
 Describe a mutex_t for logging.
 
#define NAME_DESCRIBE_RWLOCK(l)   named_describe((uintptr_t)(const void *)(l), "rwlock")
 Describe an rwlock_t for logging.
 
#define NAME_DESCRIBE_COND(c)   named_describe((uintptr_t)(const void *)(c), "cond")
 Describe a cond_t for logging.
 
#define NAME_DESCRIBE_THREAD(t)   named_describe_thread(t)
 Describe a thread for logging.
 
#define NAME_DESCRIBE_TRANSPORT(tr)   named_describe((uintptr_t)(const void *)(tr), "transport")
 Describe a transport for logging.
 
#define NAME_DESCRIBE_SOCKET(fd)   named_describe((uintptr_t)(intptr_t)(fd), "socket")
 Describe a socket for logging.
 
#define NAME_DESCRIBE_RINGBUF(rb)   named_describe((uintptr_t)(const void *)(rb), "ringbuf")
 Describe a ring buffer for logging.
 

Detailed Description

This module provides a centralized registry for naming any addressable resource: mutexes, threads, sockets, ring buffers, network connections, etc.

Any value that fits in a uintptr_t can be registered with a human-readable name. Names are auto-suffixed with a unique ID (e.g., "recv_mutex.7") to distinguish multiple instances of the same conceptual resource.

The registry is thread-safe and zero-overhead in release builds (NDEBUG).

Note
Registry is not thread-safe for unregistration during unwind. Always unregister resources before they become invalid (e.g., in destroy/cleanup).

USAGE EXAMPLES:

// Pointer-based (for heap objects, structs) ringbuffer_t *rb = ringbuffer_create(...); NAMED_REGISTER(rb, "recv_audio"); // auto name: "recv_audio.3" // ... use rb ... NAMED_UNREGISTER(rb); ringbuffer_destroy(rb);

// Integer handle-based (for fd, socket, etc.) int client_fd = accept(server_fd, ...); NAMED_REGISTER_ID(client_fd, "client_socket"); // ... use client_fd ... NAMED_UNREGISTER_ID(client_fd); close(client_fd);

// Describing in logs log_info("Data received on %s", NAME_DESCRIBE_SOCKET(fd)); // Output: "socket: client_socket.2 (0x8)"

Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
February 2026

Macro Definition Documentation

◆ NAME_DESCRIBE_COND

#define NAME_DESCRIBE_COND (   c)    named_describe((uintptr_t)(const void *)(c), "cond")

#include <named.h>

Describe a cond_t for logging.

Parameters
cPointer to cond_t

Definition at line 805 of file debug/named.h.

◆ NAME_DESCRIBE_MUTEX

#define NAME_DESCRIBE_MUTEX (   m)    named_describe((uintptr_t)(const void *)(m), "mutex")

#include <named.h>

Describe a mutex_t for logging.

Parameters
mPointer to mutex_t

Definition at line 791 of file debug/named.h.

◆ NAME_DESCRIBE_RINGBUF

#define NAME_DESCRIBE_RINGBUF (   rb)    named_describe((uintptr_t)(const void *)(rb), "ringbuf")

#include <named.h>

Describe a ring buffer for logging.

Parameters
rbPointer to ringbuffer_t

Definition at line 835 of file debug/named.h.

◆ NAME_DESCRIBE_RWLOCK

#define NAME_DESCRIBE_RWLOCK (   l)    named_describe((uintptr_t)(const void *)(l), "rwlock")

#include <named.h>

Describe an rwlock_t for logging.

Parameters
lPointer to rwlock_t

Definition at line 798 of file debug/named.h.

◆ NAME_DESCRIBE_SOCKET

#define NAME_DESCRIBE_SOCKET (   fd)    named_describe((uintptr_t)(intptr_t)(fd), "socket")

#include <named.h>

Describe a socket for logging.

Parameters
fdsocket_t file descriptor

Definition at line 828 of file debug/named.h.

◆ NAME_DESCRIBE_THREAD

#define NAME_DESCRIBE_THREAD (   t)    named_describe_thread(t)

#include <named.h>

Describe a thread for logging.

Parameters
tasciichat_thread_t handle

Uses named_describe_thread() function to handle platform-specific conversion.

Definition at line 814 of file debug/named.h.

◆ NAME_DESCRIBE_TRANSPORT

#define NAME_DESCRIBE_TRANSPORT (   tr)    named_describe((uintptr_t)(const void *)(tr), "transport")

#include <named.h>

Describe a transport for logging.

Parameters
trPointer to acip_transport_t

Definition at line 821 of file debug/named.h.

◆ NAMED_DESCRIBE

#define NAMED_DESCRIBE (   ptr,
  hint 
)    named_describe((uintptr_t)(const void *)(ptr), (hint))

#include <named.h>

Describe a pointer in log format.

Parameters
ptrObject pointer
hintType hint string (e.g., "mutex")

Definition at line 356 of file debug/named.h.

◆ NAMED_DESCRIBE_ID

#define NAMED_DESCRIBE_ID (   id,
  hint 
)    named_describe((uintptr_t)(intptr_t)(id), (hint))

#include <named.h>

Describe an integer handle in log format.

Parameters
idInteger handle
hintType hint string (e.g., "socket")

Definition at line 388 of file debug/named.h.

◆ NAMED_GET

#define NAMED_GET (   ptr)    named_get((uintptr_t)(const void *)(ptr))

#include <named.h>

Look up registered name for a pointer.

Parameters
ptrObject pointer

Definition at line 348 of file debug/named.h.

◆ NAMED_GET_BY_INT

#define NAMED_GET_BY_INT (   id,
  buffer,
  size 
)

#include <named.h>

Value:
do { \
const char *_name = named_get((uintptr_t)(id)); \
if (_name) { \
size_t _len = strlen(_name); \
if (_len >= (size)) _len = (size) - 1; \
memcpy((buffer), (_name), _len); \
(buffer)[_len] = '\0'; \
} else { \
snprintf((buffer), (size), "0x%lx", (unsigned long)(id)); \
} \
} while (0)
const char * named_get(uintptr_t key)
Look up the registered name for a resource.

Get name of an integer ID or format as hex fallback.

Parameters
idThe integer ID to look up (e.g., thread ID, FD, packet type)
bufferOutput buffer for the result
sizeSize of the output buffer

Tries to look up the registered name for an integer ID. If found, copies it to buffer. If not found, formats the ID as "0x%lx" (hexadecimal).

Use this for thread IDs and other small integer identifiers. In release builds (NDEBUG), always formats as hex.

Definition at line 1060 of file debug/named.h.

1061 { \
1062 const char *_name = named_get((uintptr_t)(id)); \
1063 if (_name) { \
1064 size_t _len = strlen(_name); \
1065 if (_len >= (size)) _len = (size) - 1; \
1066 memcpy((buffer), (_name), _len); \
1067 (buffer)[_len] = '\0'; \
1068 } else { \
1069 snprintf((buffer), (size), "0x%lx", (unsigned long)(id)); \
1070 } \
1071 } while (0)

◆ NAMED_GET_BY_PTR

#define NAMED_GET_BY_PTR (   key,
  buffer,
  size 
)

#include <named.h>

Value:
do { \
const char *_name = named_get(key); \
if (_name) { \
size_t _len = strlen(_name); \
if (_len >= (size)) _len = (size) - 1; \
memcpy((buffer), (_name), _len); \
(buffer)[_len] = '\0'; \
} else { \
snprintf((buffer), (size), "0x%tx", (ptrdiff_t)(key)); \
} \
} while (0)

Get name of a pointer/key or format as address fallback.

Parameters
keyThe uintptr_t key to look up
bufferOutput buffer for the result
sizeSize of the output buffer

Tries to look up the registered name for the key. If found, copies it to buffer. If not found, formats the key as "0x%tx" (hexadecimal address).

Useful in hot paths like logging where you want the name if available, but need a reasonable fallback for unregistered keys.

In release builds (NDEBUG), always formats as address.

Definition at line 1034 of file debug/named.h.

1035 { \
1036 const char *_name = named_get(key); \
1037 if (_name) { \
1038 size_t _len = strlen(_name); \
1039 if (_len >= (size)) _len = (size) - 1; \
1040 memcpy((buffer), (_name), _len); \
1041 (buffer)[_len] = '\0'; \
1042 } else { \
1043 snprintf((buffer), (size), "0x%tx", (ptrdiff_t)(key)); \
1044 } \
1045 } while (0)

◆ NAMED_GET_BY_STR

#define NAMED_GET_BY_STR (   str,
  buffer,
  size 
)

#include <named.h>

Value:
do { \
if ((str)) { \
strncpy((buffer), (str), (size) - 1); \
(buffer)[(size) - 1] = '\0'; \
} else { \
(buffer)[0] = '\0'; \
} \
} while (0)

Copy a string to buffer, with bounds checking.

Parameters
strThe string to copy (may be NULL)
bufferOutput buffer
sizeSize of the output buffer

Safe string copy that handles NULL inputs and ensures null termination. Useful for formatting optional or variable string fields.

In release builds (NDEBUG), copies the string as-is.

Definition at line 1085 of file debug/named.h.

1086 { \
1087 if ((str)) { \
1088 strncpy((buffer), (str), (size) - 1); \
1089 (buffer)[(size) - 1] = '\0'; \
1090 } else { \
1091 (buffer)[0] = '\0'; \
1092 } \
1093 } while (0)

◆ NAMED_OPEN

#define NAMED_OPEN (   pathname,
  name,
  flags,
  ... 
)

#include <named.h>

Value:
({ \
int _fd; \
if ((flags) & O_CREAT) { \
_fd = platform_open((pathname), (flags), __VA_ARGS__); \
} else { \
_fd = platform_open((pathname), (flags)); \
} \
if (_fd >= 0) { \
named_register_fd(_fd, NULL, __FILE__, __LINE__, __func__); \
} \
_fd; \
})
int platform_open(const char *name, const char *pathname, int flags,...)
Safe file open (open replacement)

Open a file and register the file descriptor.

Parameters
pathnameFile path to open
nameDebug name for the file descriptor
flagsOpen flags (O_RDONLY, O_WRONLY, etc.)
...Optional mode argument for O_CREAT

Convenience macro that opens a file and registers the returned FD. Automatically uses "%d" format specifier for file descriptor integers.

Usage: int fd = NAMED_OPEN("/path/to/file", "myfile", O_RDONLY); int fd = NAMED_OPEN("/path/to/file", "myfile", O_CREAT | O_WRONLY, 0644);

Definition at line 692 of file debug/named.h.

693 { \
694 int _fd; \
695 if ((flags) & O_CREAT) { \
696 _fd = platform_open((pathname), (flags), __VA_ARGS__); \
697 } else { \
698 _fd = platform_open((pathname), (flags)); \
699 } \
700 if (_fd >= 0) { \
701 named_register_fd(_fd, NULL, __FILE__, __LINE__, __func__); \
702 } \
703 _fd; \
704 })

◆ NAMED_REGISTER

#define NAMED_REGISTER (   ptr,
  name,
  type,
  fmt,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(ptr), (name), (type), (fmt), __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register any pointer with base name, type, format spec, and location (auto-suffix)

Parameters
ptrObject pointer (void* or typed pointer)
nameBase name string
typeData type label (e.g., "mutex", "socket")
fmtFormat specifier for printing (e.g., "0x%tx")

In debug builds, automatically captures FILE, LINE, and func for location info. In release builds (NDEBUG), this is a no-op.

Definition at line 317 of file debug/named.h.

◆ NAMED_REGISTER_APP_CLIENT

#define NAMED_REGISTER_APP_CLIENT (   client,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(client), (name), "app_client", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an app client with automatic format specifier.

Parameters
clientApp client pointer
nameBase name string

Definition at line 894 of file debug/named.h.

◆ NAMED_REGISTER_ATOMIC

#define NAMED_REGISTER_ATOMIC (   a,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(a), (name), "atomic", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an atomic_t with automatic format specifier.

Parameters
aPointer to atomic_t
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for atomic addresses.

Definition at line 735 of file debug/named.h.

◆ NAMED_REGISTER_ATOMIC_PTR

#define NAMED_REGISTER_ATOMIC_PTR (   a,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(a), (name), "atomic_ptr", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an _Atomic(void *) with automatic format specifier.

Parameters
aPointer to _Atomic(void *)
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for atomic_ptr addresses.

Definition at line 746 of file debug/named.h.

◆ NAMED_REGISTER_AUDIO_CODEC

#define NAMED_REGISTER_AUDIO_CODEC (   codec,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(codec), (name), "audio_codec", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an audio codec with automatic format specifier.

Parameters
codecAudio codec pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for audio codec addresses.

Definition at line 561 of file debug/named.h.

◆ NAMED_REGISTER_AUDIO_CONTEXT

#define NAMED_REGISTER_AUDIO_CONTEXT (   ctx,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(ctx), (name), "audio_context", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an audio context with automatic format specifier.

Parameters
ctxAudio context pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for audio context addresses.

Definition at line 641 of file debug/named.h.

◆ NAMED_REGISTER_AUDIO_RINGBUF

#define NAMED_REGISTER_AUDIO_RINGBUF (   buf,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(buf), (name), "audio_ringbuf", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an audio ring buffer with automatic format specifier.

Parameters
bufAudio ring buffer pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for ring buffer addresses.

Definition at line 539 of file debug/named.h.

◆ NAMED_REGISTER_BUFFER_POOL

#define NAMED_REGISTER_BUFFER_POOL (   pool,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(pool), (name), "buffer_pool", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a buffer pool with automatic format specifier.

Parameters
poolBuffer pool pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for buffer pool addresses.

Definition at line 583 of file debug/named.h.

◆ NAMED_REGISTER_CLIENT

#define NAMED_REGISTER_CLIENT (   client,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(client), (name), "client", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a client connection with automatic format specifier.

Parameters
clientClient pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for client addresses.

Definition at line 484 of file debug/named.h.

◆ NAMED_REGISTER_CLIENT_AUDIO_PIPELINE

#define NAMED_REGISTER_CLIENT_AUDIO_PIPELINE (   pipeline,
  name,
  parent_ptr 
)

#include <named.h>

Value:
named_register((uintptr_t)(const void *)(pipeline), (name), "client_audio_pipeline", "0x%tx", __FILE__, __LINE__, \
__func__, (uintptr_t)(const void *)(parent_ptr))
const char * named_register(uintptr_t key, const char *base_name, const char *type, const char *format_spec, const char *file, int line, const char *func, uintptr_t parent_key)
Register a resource with an auto-suffixed name, type, and location info.

Register a client audio pipeline with automatic format specifier.

Parameters
pipelineClient audio pipeline pointer
nameBase name string

Definition at line 948 of file debug/named.h.

◆ NAMED_REGISTER_COND

#define NAMED_REGISTER_COND (   cond,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(cond), (name), "cond", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a condition variable with automatic format specifier.

Parameters
condCondition variable pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for cond addresses.

Definition at line 428 of file debug/named.h.

◆ NAMED_REGISTER_CONTEXT

#define NAMED_REGISTER_CONTEXT (   context,
  context_type,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(context), (name), (context_type), "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a generic context with automatic format specifier.

Parameters
contextAny context pointer
context_typeType string (e.g., "ssl_context", "decoder_context")
nameBase name string

Convenience macro for naming any opaque context. Automatically uses "0x%tx" format. Usage: NAMED_REGISTER_CONTEXT(ctx, "ssl_context", "tls_server");

Definition at line 1016 of file debug/named.h.

◆ NAMED_REGISTER_CRYPTO_CONTEXT

#define NAMED_REGISTER_CRYPTO_CONTEXT (   ctx,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(ctx), (name), "crypto", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a crypto context with automatic format specifier.

Parameters
ctxCrypto context pointer
nameBase name string (typically "crypto_client_<id>")

Convenience macro that automatically uses "0x%tx" format specifier for crypto context addresses.

Definition at line 495 of file debug/named.h.

◆ NAMED_REGISTER_DATACHANNEL

#define NAMED_REGISTER_DATACHANNEL (   datachannel,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(datachannel), (name), "datachannel", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a data channel with automatic format specifier.

Parameters
datachannelData channel pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for datachannel addresses.

Definition at line 462 of file debug/named.h.

◆ NAMED_REGISTER_FD

#define NAMED_REGISTER_FD (   fd,
  name 
)    named_register_fd((fd), (name), __FILE__, __LINE__, __func__)

#include <named.h>

Register an existing file descriptor.

Parameters
fdFile descriptor (must be >= 0)
nameHuman-readable name for the fd (e.g., "inhibit"), or NULL for auto-generated

Convenience macro for registering file descriptors that are already open. If name is non-NULL, registers as "name (fd=N)"; otherwise uses "fd=N". In release builds (NDEBUG), this is a no-op.

Definition at line 725 of file debug/named.h.

◆ NAMED_REGISTER_FFMPEG_CONTEXT

#define NAMED_REGISTER_FFMPEG_CONTEXT (   context,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(context), (name), "ffmpeg_context", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an FFmpeg decoder context with automatic format specifier.

Parameters
contextFFmpeg context pointer (AVFormatContext * or similar)
nameBase name string (e.g., "ffmpeg_decoder")

Convenience macro for naming FFmpeg contexts. Automatically uses "0x%tx" format. Usage: NAMED_REGISTER_FFMPEG_CONTEXT(avctx, "ffmpeg_input");

Definition at line 1003 of file debug/named.h.

◆ NAMED_REGISTER_FFMPEG_DECODER

#define NAMED_REGISTER_FFMPEG_DECODER (   decoder,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(decoder), (name), "ffmpeg_decoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an FFmpeg decoder with automatic format specifier.

Parameters
decoderFFmpeg decoder pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for decoder addresses.

Definition at line 594 of file debug/named.h.

◆ NAMED_REGISTER_FFMPEG_ENCODER

#define NAMED_REGISTER_FFMPEG_ENCODER (   encoder,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(encoder), (name), "ffmpeg_encoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an FFmpeg encoder with automatic format specifier.

Parameters
encoderFFmpeg encoder pointer
nameBase name string
parent_ptrParent context pointer (uintptr_t cast)

Convenience macro that automatically uses "0x%tx" format specifier for encoder addresses.

Definition at line 606 of file debug/named.h.

◆ NAMED_REGISTER_FMT

#define NAMED_REGISTER_FMT (   ptr,
  type,
  fmt_spec,
  fmt,
  ... 
)

#include <named.h>

Value:
named_register_fmt((uintptr_t)(const void *)(ptr), (type), (fmt_spec), __FILE__, __LINE__, __func__, (fmt), \
__VA_ARGS__)
const char * named_register_fmt(uintptr_t key, const char *type, const char *format_spec, const char *file, int line, const char *func, const char *fmt,...)
Register a resource with a formatted name, type, and location info (no auto-suffix)

Register with a formatted name, type, and format spec.

Parameters
ptrObject pointer
typeData type label
fmt_specFormat specifier for printing (e.g., "0x%tx")
fmtPrintf-style format string for name
...Format arguments

In debug builds, automatically captures FILE, LINE, and func for location info. In release builds (NDEBUG), this is a no-op.

Definition at line 332 of file debug/named.h.

◆ NAMED_REGISTER_FRAME_BUFFER

#define NAMED_REGISTER_FRAME_BUFFER (   buf,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(buf), (name), "frame_buffer", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a frame buffer with automatic format specifier.

Parameters
bufFrame buffer pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for frame buffer addresses.

Definition at line 517 of file debug/named.h.

◆ NAMED_REGISTER_H265_DECODER

#define NAMED_REGISTER_H265_DECODER (   decoder,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(decoder), (name), "h265_decoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an H.265 decoder with automatic format specifier.

Parameters
decoderH.265 decoder pointer
nameBase name string
parent_ptrParent context pointer (uintptr_t cast)

Convenience macro that automatically uses "0x%tx" format specifier for H.265 decoder addresses.

Definition at line 630 of file debug/named.h.

◆ NAMED_REGISTER_H265_ENCODER

#define NAMED_REGISTER_H265_ENCODER (   encoder,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(encoder), (name), "h265_encoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an H.265 encoder with automatic format specifier.

Parameters
encoderH.265 encoder pointer
nameBase name string
parent_ptrParent context pointer (uintptr_t cast)

Convenience macro that automatically uses "0x%tx" format specifier for H.265 encoder addresses.

Definition at line 618 of file debug/named.h.

◆ NAMED_REGISTER_ID

#define NAMED_REGISTER_ID (   id,
  name,
  type,
  fmt,
  parent_ptr 
)     named_register((uintptr_t)(intptr_t)(id), (name), (type), (fmt), __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an integer handle (fd, socket, etc.) with type.

Parameters
idInteger handle (socket_t, int, etc.)
nameBase name string
typeData type label (e.g., "socket", "fd")

In debug builds, automatically captures FILE, LINE, and func for location info. In release builds (NDEBUG), this is a no-op.

Definition at line 372 of file debug/named.h.

◆ NAMED_REGISTER_LWS_CONTEXT

#define NAMED_REGISTER_LWS_CONTEXT (   context,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(context), (name), "lws_context", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a libwebsockets context with automatic format specifier.

Parameters
contextLWS context pointer (struct lws_context *)
nameBase name string (e.g., "ws_server" or "ws_client")

Convenience macro for naming libwebsockets contexts. Automatically uses "0x%tx" format. Usage: NAMED_REGISTER_LWS_CONTEXT(lws_ctx, "ws_server");

Definition at line 991 of file debug/named.h.

◆ NAMED_REGISTER_MEDIA_SOURCE

#define NAMED_REGISTER_MEDIA_SOURCE (   source,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(source), (name), "media_source", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a media source with automatic format specifier.

Parameters
sourceMedia source pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for media source addresses.

Definition at line 674 of file debug/named.h.

◆ NAMED_REGISTER_MIXER

#define NAMED_REGISTER_MIXER (   mixer,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(mixer), (name), "mixer", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an audio mixer with automatic format specifier.

Parameters
mixerMixer pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for mixer addresses.

Definition at line 550 of file debug/named.h.

◆ NAMED_REGISTER_MUTEX

#define NAMED_REGISTER_MUTEX (   mutex,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(mutex), (name), "mutex", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a mutex with automatic format specifier.

Parameters
mutexMutex pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for mutex addresses.

Definition at line 402 of file debug/named.h.

◆ NAMED_REGISTER_NODE_POOL

#define NAMED_REGISTER_NODE_POOL (   pool,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(pool), (name), "node_pool", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a node pool with automatic format specifier.

Parameters
poolNode pool pointer
nameBase name string

Definition at line 912 of file debug/named.h.

◆ NAMED_REGISTER_OPTIONS_BUILDER

#define NAMED_REGISTER_OPTIONS_BUILDER (   builder,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(builder), (name), "options_builder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an options builder with automatic format specifier.

Parameters
builderOptions builder pointer
nameBase name string

Definition at line 930 of file debug/named.h.

◆ NAMED_REGISTER_PACKET_QUEUE

#define NAMED_REGISTER_PACKET_QUEUE (   queue,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(queue), (name), "packet_queue", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a packet queue with automatic format specifier.

Parameters
queuePacket queue pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for packet queue addresses.

Definition at line 528 of file debug/named.h.

◆ NAMED_REGISTER_RATE_LIMITER

#define NAMED_REGISTER_RATE_LIMITER (   limiter,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(limiter), (name), "rate_limiter", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a rate limiter with automatic format specifier.

Parameters
limiterRate limiter pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for rate limiter addresses.

Definition at line 652 of file debug/named.h.

◆ NAMED_REGISTER_RWLOCK

#define NAMED_REGISTER_RWLOCK (   lock,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(lock), (name), "rwlock", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register an rwlock with automatic format specifier.

Parameters
lockRWLock pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for rwlock addresses.

Definition at line 414 of file debug/named.h.

◆ NAMED_REGISTER_SIMPLE_FRAME_SWAP

#define NAMED_REGISTER_SIMPLE_FRAME_SWAP (   swap,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(swap), (name), "simple_frame_swap", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a simple frame swap with automatic format specifier.

Parameters
swapSimple frame swap pointer
nameBase name string

Definition at line 939 of file debug/named.h.

◆ NAMED_REGISTER_SOCKET

#define NAMED_REGISTER_SOCKET (   socket,
  name,
  parent_ptr 
)     named_register((uintptr_t)(intptr_t)(socket), (name), "socket", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a socket with automatic format specifier.

Parameters
socketSocket pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for socket addresses.

Definition at line 439 of file debug/named.h.

◆ NAMED_REGISTER_TCP_CLIENT

#define NAMED_REGISTER_TCP_CLIENT (   client,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(client), (name), "tcp_client", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a TCP client with automatic format specifier.

Parameters
clientTCP client pointer
nameBase name string

Definition at line 876 of file debug/named.h.

◆ NAMED_REGISTER_THREAD

#define NAMED_REGISTER_THREAD (   thread,
  name,
  parent_ptr 
)     named_register(asciichat_thread_to_key((thread)), (name), "thread", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a thread handle with name and automatic format specifier.

Parameters
threadasciichat_thread_t handle (NOT a pointer)
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for thread addresses. In debug builds, automatically captures FILE, LINE, and func for location info. The thread handle itself (not a pointer) is used as the registry key. In release builds (NDEBUG), this is a no-op.

Definition at line 764 of file debug/named.h.

◆ NAMED_REGISTER_THREAD_POOL

#define NAMED_REGISTER_THREAD_POOL (   pool,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(pool), (name), "thread_pool", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a thread pool with automatic format specifier.

Parameters
poolThread pool pointer
nameBase name string

Definition at line 921 of file debug/named.h.

◆ NAMED_REGISTER_THREADPOOL_WORK

#define NAMED_REGISTER_THREADPOOL_WORK (   work,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(work), (name), "work", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a thread pool work item with automatic format specifier.

Parameters
workWork item pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for work item addresses.

Definition at line 473 of file debug/named.h.

◆ NAMED_REGISTER_TRANSPORT

#define NAMED_REGISTER_TRANSPORT (   transport,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(transport), (name), "transport", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a transport with automatic format specifier.

Parameters
transportTransport pointer
nameBase name string (typically "transport_client_<id>" or "transport_tcp_<id>")

Convenience macro that automatically uses "0x%tx" format specifier for transport addresses.

Definition at line 506 of file debug/named.h.

◆ NAMED_REGISTER_VIDEO_ENCODER

#define NAMED_REGISTER_VIDEO_ENCODER (   encoder,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(encoder), (name), "video_encoder", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a video encoder with automatic format specifier.

Parameters
encoderVideo encoder pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for video encoder addresses.

Definition at line 572 of file debug/named.h.

◆ NAMED_REGISTER_VIDEO_FRAME_BUFFER

#define NAMED_REGISTER_VIDEO_FRAME_BUFFER (   buf,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(buf), (name), "video_frame_buffer", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a video frame buffer with automatic format specifier.

Parameters
bufVideo frame buffer pointer
nameBase name string

Definition at line 903 of file debug/named.h.

◆ NAMED_REGISTER_WAV_WRITER

#define NAMED_REGISTER_WAV_WRITER (   writer,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(writer), (name), "wav_writer", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a WAV writer with automatic format specifier.

Parameters
writerWAV writer pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for WAV writer addresses.

Definition at line 663 of file debug/named.h.

◆ NAMED_REGISTER_WEBSOCKET

#define NAMED_REGISTER_WEBSOCKET (   websocket,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(websocket), (name), "websocket", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a WebSocket connection with automatic format specifier.

Parameters
websocketWebSocket pointer
nameBase name string

Convenience macro that automatically uses "0x%tx" format specifier for websocket addresses.

Definition at line 451 of file debug/named.h.

◆ NAMED_REGISTER_WEBSOCKET_CLIENT

#define NAMED_REGISTER_WEBSOCKET_CLIENT (   client,
  name,
  parent_ptr 
)     named_register((uintptr_t)(const void *)(client), (name), "websocket_client", "0x%tx", __FILE__, __LINE__, __func__, (uintptr_t)(const void *)(parent_ptr))

#include <named.h>

Register a WebSocket client with automatic format specifier.

Parameters
clientWebSocket client pointer
nameBase name string

Definition at line 885 of file debug/named.h.

◆ NAMED_REGISTER_WEBSOCKET_IMPL

#define NAMED_REGISTER_WEBSOCKET_IMPL (   data,
  name,
  parent_ptr 
)    ((void)(data), (void)(name), (void)(parent_ptr))

#include <named.h>

Definition at line 956 of file debug/named.h.

◆ NAMED_UNREGISTER

#define NAMED_UNREGISTER (   ptr)    named_unregister((uintptr_t)(const void *)(ptr))

#include <named.h>

Unregister a pointer.

Parameters
ptrObject pointer

Definition at line 341 of file debug/named.h.

◆ NAMED_UNREGISTER_FD

#define NAMED_UNREGISTER_FD (   fd)    NAMED_UNREGISTER_ID((fd))

#include <named.h>

Unregister a file descriptor.

Parameters
fdFile descriptor to unregister

Call this before closing a named file descriptor.

Definition at line 713 of file debug/named.h.

◆ NAMED_UNREGISTER_ID

#define NAMED_UNREGISTER_ID (   id)    named_unregister((uintptr_t)(intptr_t)(id))

#include <named.h>

Unregister an integer handle.

Parameters
idInteger handle

Definition at line 380 of file debug/named.h.

◆ NAMED_UNREGISTER_SOCKET

#define NAMED_UNREGISTER_SOCKET (   socket)    NAMED_UNREGISTER_ID((socket))

#include <named.h>

Definition at line 441 of file debug/named.h.

◆ NAMED_UNREGISTER_THREAD

#define NAMED_UNREGISTER_THREAD (   thread)    named_unregister(asciichat_thread_to_key((thread)))

#include <named.h>

Unregister a thread handle.

Parameters
threadasciichat_thread_t handle (NOT a pointer)

Definition at line 772 of file debug/named.h.

Typedef Documentation

◆ named_iter_callback_t

typedef void(* named_iter_callback_t) (uintptr_t key, const char *name, void *user_data)

#include <named.h>

Callback function for iterating registered entries.

Parameters
keyThe registered key (uintptr_t)
nameThe registered name string
user_dataUser-provided context pointer

Called for each entry in the registry. The callback should not modify the registry during iteration.

Definition at line 868 of file debug/named.h.

Function Documentation

◆ asciichat_thread_to_key()

uintptr_t asciichat_thread_to_key ( asciichat_thread_t  thread)

#include <named.h>

Convert a thread handle to a registry key.

Parameters
threadThread handle (asciichat_thread_t)
Returns
uintptr_t suitable for registry lookups

Platform-specific conversion. On POSIX, pthread_t is cast directly. On Windows, HANDLE is cast directly.

This function is defined in lib/platform/posix/thread.c or lib/platform/windows/thread.c

Definition at line 87 of file threading.c.

87 {
88 return (uintptr_t)thread;
89}

◆ named_describe()

const char * named_describe ( uintptr_t  key,
const char *  type_hint 
)

#include <named.h>

Format a description string for logging.

Parameters
keyThe resource key
type_hintA type label (e.g., "mutex", "socket", "thread")
Returns
Description string in format "type_hint: name (0xKEY)" or type_hint if not registered

Returns a per-thread static buffer suitable for a single log call. The buffer is overwritten on the next call to this function within the same thread. Do not store or free the returned pointer.

If the key is not registered, returns just the type_hint. In release builds (NDEBUG), this always returns "?".

Definition at line 368 of file debug/named.c.

368 {
369 if (!type_hint)
370 type_hint = "object";
371
372 static _Thread_local char buffer[DESCRIBE_BUFFER_SIZE];
373
374 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
375 snprintf(buffer, sizeof(buffer), "%s (0x%tx)", type_hint, (ptrdiff_t)key);
376 return buffer;
377 }
378
379 rwlock_rdlock(&g_named_registry.entries_lock);
380 named_entry_t *entry = NULL;
381 HASH_FIND(hh, g_named_registry.entries, &key, sizeof(uintptr_t), entry);
382 rwlock_rdunlock(&g_named_registry.entries_lock);
383
384 if (entry) {
385 const char *type = entry->type ? entry->type : type_hint;
386 const char *name = entry->name ? entry->name : "unknown";
387 if (entry->file && entry->func && entry->line > 0) {
388 snprintf(buffer, sizeof(buffer), "%s/%s (0x%tx) @ %s:%d:%s()", type, name, (ptrdiff_t)key, entry->file,
389 entry->line, entry->func);
390 } else {
391 snprintf(buffer, sizeof(buffer), "%s/%s (0x%tx)", type, name, (ptrdiff_t)key);
392 }
393 } else {
394 snprintf(buffer, sizeof(buffer), "%s (0x%tx)", type_hint ? type_hint : "unknown", (ptrdiff_t)key);
395 }
396
397 return buffer;
398}
#define DESCRIBE_BUFFER_SIZE
Definition debug/named.c:32
#define rwlock_rdlock(lock)
Acquire a read lock (with debug tracking in debug builds)
Definition rwlock.h:294
#define rwlock_rdunlock(lock)
Release a read lock (with debug tracking in debug builds)
Definition rwlock.h:331
bool lifecycle_is_initialized(const lifecycle_t *lc)
Definition lifecycle.c:155
Registry entry for uthash.
Definition debug/named.c:59
char * func
Definition debug/named.c:66
char * file
Definition debug/named.c:64
int line
Definition debug/named.c:65
char * name
Definition debug/named.c:61
char * type
Definition debug/named.c:62
rwlock_t entries_lock
Definition debug/named.c:79
lifecycle_t lifecycle
Definition debug/named.c:80
named_entry_t * entries
Definition debug/named.c:78

References DESCRIBE_BUFFER_SIZE, named_registry_t::entries, named_registry_t::entries_lock, named_entry::file, named_entry::func, named_registry_t::lifecycle, lifecycle_is_initialized(), named_entry::line, named_entry::name, rwlock_rdlock, rwlock_rdunlock, and named_entry::type.

Referenced by named_describe_thread().

◆ named_describe_thread()

const char * named_describe_thread ( void *  thread)

#include <named.h>

Describe a thread for logging (function wrapper)

Parameters
threadasciichat_thread_t handle
Returns
Description string "thread: name (0xID)"

This is a function (not a macro) to handle the opaque asciichat_thread_t type properly, converting it through asciichat_thread_to_key().

Definition at line 400 of file debug/named.c.

400 {
401 uintptr_t key = asciichat_thread_to_key((asciichat_thread_t)thread);
402 return named_describe(key, "thread");
403}
const char * named_describe(uintptr_t key, const char *type_hint)
Format a description string for logging.
uintptr_t asciichat_thread_to_key(asciichat_thread_t thread)
Convert a thread handle to a registry key.
Definition threading.c:87
void * asciichat_thread_t

References asciichat_thread_to_key(), and named_describe().

◆ named_destroy()

void named_destroy ( void  )

#include <named.h>

Destroy the named object registry.

Cleans up all registered names and internal structures. Typically called from lock_debug_destroy().

Definition at line 108 of file debug/named.c.

108 {
109 // Always attempt to shut down the lifecycle, but always cleanup entries
110 lifecycle_shutdown(&g_named_registry.lifecycle);
111
112 rwlock_wrlock(&g_named_registry.entries_lock);
113
114 // Find the registry's own rwlock entry (allocated during named_init bootstrap)
115 // This entry will be unregistered by rwlock_destroy, so we must not free it here
116 uintptr_t registry_lock_key = (uintptr_t)(const void *)&g_named_registry.entries_lock;
117 named_entry_t *registry_lock_entry = NULL;
118 HASH_FIND(hh, g_named_registry.entries, &registry_lock_key, sizeof(uintptr_t), registry_lock_entry);
119
120 for (named_entry_t *e = g_named_registry.entries; e != NULL;) {
121 named_entry_t *next = e->hh.next;
122
123 // Skip the registry lock entry - it will be cleaned up by rwlock_destroy
124 // which calls NAMED_UNREGISTER after we release the lock
125 if (e == registry_lock_entry) {
126 e = next;
127 continue;
128 }
129
130 // Free all other entries
131 free(e->name);
132 if (e->type)
133 free(e->type);
134 if (e->format_spec)
135 free(e->format_spec);
136 if (e->file)
137 free(e->file);
138 if (e->func)
139 free(e->func);
140 free(e);
141 e = next;
142 }
143
144 rwlock_wrunlock(&g_named_registry.entries_lock);
145
146 // rwlock_destroy will call NAMED_UNREGISTER on the lock entry, which will:
147 // 1. Acquire the lock (now safe since we released it)
148 // 2. Find and remove the lock entry from the hash
149 // 3. Free the lock entry's fields
150 rwlock_destroy(&g_named_registry.entries_lock);
151}
#define rwlock_wrunlock(lock)
Release a write lock (with debug tracking in debug builds)
Definition rwlock.h:349
int rwlock_destroy(rwlock_t *lock)
Destroy a read-write lock.
#define rwlock_wrlock(lock)
Acquire a write lock (with debug tracking in debug builds)
Definition rwlock.h:313
bool lifecycle_shutdown(lifecycle_t *lc)
Definition lifecycle.c:108
UT_hash_handle hh
Definition debug/named.c:67

References named_registry_t::entries, named_registry_t::entries_lock, named_entry::hh, named_registry_t::lifecycle, lifecycle_shutdown(), rwlock_destroy(), rwlock_wrlock, and rwlock_wrunlock.

Referenced by asciichat_shared_destroy().

◆ named_get()

const char * named_get ( uintptr_t  key)

#include <named.h>

Look up the registered name for a resource.

Parameters
keyThe resource key
Returns
Registered name string, or NULL if not registered

Returns the name string registered with named_register() or named_register_fmt(), or NULL if the key is not in the registry.

In release builds (NDEBUG), this always returns NULL.

Definition at line 329 of file debug/named.c.

329 {
330 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
331 return NULL;
332 }
333
334 rwlock_rdlock(&g_named_registry.entries_lock);
335 named_entry_t *entry = NULL;
336 HASH_FIND(hh, g_named_registry.entries, &key, sizeof(uintptr_t), entry);
337 const char *result = entry ? entry->name : NULL;
338 rwlock_rdunlock(&g_named_registry.entries_lock);
339 return result;
340}

References named_registry_t::entries, named_registry_t::entries_lock, named_registry_t::lifecycle, lifecycle_is_initialized(), named_entry::name, rwlock_rdlock, and rwlock_rdunlock.

Referenced by log_named_format_message(), and log_template_apply().

◆ named_get_by_type_and_id()

const char * named_get_by_type_and_id ( const char *  type_name,
size_t  type_len,
int  id 
)

#include <named.h>

Look up an integer ID by type name and value.

Parameters
type_nameType string (e.g., "socket", "client", "connection")
type_lenLength of type name
idInteger ID value to look up
Returns
Registered name string, or NULL if not found

Searches the registry for entries matching the given type and integer ID. Enables formatting of patterns like "socket 12" → "socket/server_listener (socket=12)". In release builds (NDEBUG), this always returns NULL.

Referenced by log_named_format_message().

◆ named_get_fd()

const char * named_get_fd ( int  fd)

#include <named.h>

Look up a registered file descriptor.

Parameters
fdFile descriptor value
Returns
Registered name string, or NULL if not registered

Looks up an FD using the same namespace encoding as named_register_fd(). In release builds (NDEBUG), this always returns NULL.

Definition at line 492 of file debug/named.c.

492 {
493 if (fd < 0)
494 return NULL;
495
496 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
497 return NULL;
498 }
499
500 uintptr_t key = encode_fd_key(fd);
501 rwlock_rdlock(&g_named_registry.entries_lock);
502 named_entry_t *entry = NULL;
503 HASH_FIND(hh, g_named_registry.entries, &key, sizeof(uintptr_t), entry);
504 const char *result = entry ? entry->name : NULL;
505 rwlock_rdunlock(&g_named_registry.entries_lock);
506 return result;
507}

References named_registry_t::entries, named_registry_t::entries_lock, named_registry_t::lifecycle, lifecycle_is_initialized(), named_entry::name, rwlock_rdlock, and rwlock_rdunlock.

Referenced by log_named_format_message().

◆ named_get_fd_format_spec()

const char * named_get_fd_format_spec ( int  fd)

#include <named.h>

Get the format specifier for a registered file descriptor.

Parameters
fdFile descriptor value
Returns
Format specifier string (e.g., "%d"), or NULL if not registered

Definition at line 509 of file debug/named.c.

509 {
510 if (fd < 0)
511 return NULL;
512
513 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
514 return NULL;
515 }
516
517 uintptr_t key = encode_fd_key(fd);
518 rwlock_rdlock(&g_named_registry.entries_lock);
519 named_entry_t *entry = NULL;
520 HASH_FIND(hh, g_named_registry.entries, &key, sizeof(uintptr_t), entry);
521 const char *result = entry ? entry->format_spec : NULL;
522 rwlock_rdunlock(&g_named_registry.entries_lock);
523 return result;
524}
char * format_spec
Definition debug/named.c:63

References named_registry_t::entries, named_registry_t::entries_lock, named_entry::format_spec, named_registry_t::lifecycle, lifecycle_is_initialized(), rwlock_rdlock, and rwlock_rdunlock.

◆ named_get_format_spec()

const char * named_get_format_spec ( uintptr_t  key)

#include <named.h>

Get the format specifier for a registered named object.

Parameters
keyThe resource key
Returns
Format specifier string (e.g., "0x%tx"), or NULL if not registered

Returns the format specifier registered with named_register(), or NULL if the key is not in the registry.

In release builds (NDEBUG), this always returns NULL.

Definition at line 355 of file debug/named.c.

355 {
356 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
357 return NULL;
358 }
359
360 rwlock_rdlock(&g_named_registry.entries_lock);
361 named_entry_t *entry = NULL;
362 HASH_FIND(hh, g_named_registry.entries, &key, sizeof(uintptr_t), entry);
363 const char *result = entry ? entry->format_spec : NULL;
364 rwlock_rdunlock(&g_named_registry.entries_lock);
365 return result;
366}

References named_registry_t::entries, named_registry_t::entries_lock, named_entry::format_spec, named_registry_t::lifecycle, lifecycle_is_initialized(), rwlock_rdlock, and rwlock_rdunlock.

◆ named_get_packet_type()

const char * named_get_packet_type ( int  pkt_type)

#include <named.h>

Look up a registered packet type.

Parameters
pkt_typePacket type value
Returns
Registered name string, or NULL if not registered

Looks up a packet type using the same namespace encoding as named_register_packet_type(). In release builds (NDEBUG), this always returns NULL.

Definition at line 556 of file debug/named.c.

556 {
557 if (pkt_type < 0)
558 return NULL;
559
560 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
561 return NULL;
562 }
563
564 uintptr_t key = encode_pkt_type_key(pkt_type);
565 rwlock_rdlock(&g_named_registry.entries_lock);
566 named_entry_t *entry = NULL;
567 HASH_FIND(hh, g_named_registry.entries, &key, sizeof(uintptr_t), entry);
568 const char *result = entry ? entry->name : NULL;
569 rwlock_rdunlock(&g_named_registry.entries_lock);
570 return result;
571}

References named_registry_t::entries, named_registry_t::entries_lock, named_registry_t::lifecycle, lifecycle_is_initialized(), named_entry::name, rwlock_rdlock, and rwlock_rdunlock.

Referenced by log_named_format_message().

◆ named_get_packet_type_format_spec()

const char * named_get_packet_type_format_spec ( int  pkt_type)

#include <named.h>

Get the format specifier for a registered packet type.

Parameters
pkt_typePacket type value
Returns
Format specifier string (e.g., "%d"), or NULL if not registered

Definition at line 573 of file debug/named.c.

573 {
574 if (pkt_type < 0)
575 return NULL;
576
577 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
578 return NULL;
579 }
580
581 uintptr_t key = encode_pkt_type_key(pkt_type);
582 rwlock_rdlock(&g_named_registry.entries_lock);
583 named_entry_t *entry = NULL;
584 HASH_FIND(hh, g_named_registry.entries, &key, sizeof(uintptr_t), entry);
585 const char *result = entry ? entry->format_spec : NULL;
586 rwlock_rdunlock(&g_named_registry.entries_lock);
587 return result;
588}

References named_registry_t::entries, named_registry_t::entries_lock, named_entry::format_spec, named_registry_t::lifecycle, lifecycle_is_initialized(), rwlock_rdlock, and rwlock_rdunlock.

◆ named_get_type()

const char * named_get_type ( uintptr_t  key)

#include <named.h>

Look up the registered type for a resource.

Parameters
keyThe resource key
Returns
Registered type string, or NULL if not registered

Returns the type string registered with named_register() or named_register_fmt(), or NULL if the key is not in the registry.

In release builds (NDEBUG), this always returns NULL.

Definition at line 342 of file debug/named.c.

342 {
343 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
344 return NULL;
345 }
346
347 rwlock_rdlock(&g_named_registry.entries_lock);
348 named_entry_t *entry = NULL;
349 HASH_FIND(hh, g_named_registry.entries, &key, sizeof(uintptr_t), entry);
350 const char *result = entry ? entry->type : NULL;
351 rwlock_rdunlock(&g_named_registry.entries_lock);
352 return result;
353}

References named_registry_t::entries, named_registry_t::entries_lock, named_registry_t::lifecycle, lifecycle_is_initialized(), rwlock_rdlock, rwlock_rdunlock, and named_entry::type.

Referenced by log_named_format_message().

◆ named_init()

asciichat_error_t named_init ( void  )

#include <named.h>

Initialize the named object registry.

Returns
0 on success, non-zero on error

Must be called once at startup before any named_register() calls. Typically called from lock_debug_init().

Definition at line 89 of file debug/named.c.

89 {
90 // Idempotent: if already initialized, return success
91 if (lifecycle_is_initialized(&g_named_registry.lifecycle)) {
92 return ASCIICHAT_OK;
93 }
94
95 if (!lifecycle_init(&g_named_registry.lifecycle, "named_registry")) {
96 return ASCIICHAT_OK;
97 }
98
99 if (rwlock_init(&g_named_registry.entries_lock, "named_registry_lock") != 0) {
100 lifecycle_shutdown(&g_named_registry.lifecycle);
101 return ASCIICHAT_OK; // Continue even if rwlock init fails
102 }
103
104 lifecycle_init_commit(&g_named_registry.lifecycle);
105 return ASCIICHAT_OK;
106}
@ ASCIICHAT_OK
Definition error_codes.h:51
int rwlock_init(rwlock_t *rwlock, const char *name)
Initialize a read-write lock with a name.
Definition threading.c:65
void lifecycle_init_commit(lifecycle_t *lc)
Definition lifecycle.c:90
bool lifecycle_init(lifecycle_t *lc, const char *name)
Definition lifecycle.c:26

References ASCIICHAT_OK, named_registry_t::entries_lock, named_registry_t::lifecycle, lifecycle_init(), lifecycle_init_commit(), lifecycle_is_initialized(), lifecycle_shutdown(), and rwlock_init().

Referenced by asciichat_shared_init(), and main().

◆ named_register()

const char * named_register ( uintptr_t  key,
const char *  base_name,
const char *  type,
const char *  format_spec,
const char *  file,
int  line,
const char *  func,
uintptr_t  parent_key 
)

#include <named.h>

Register a resource with an auto-suffixed name, type, and location info.

Parameters
keyA uintptr_t representing the resource (pointer or integer handle)
base_nameThe base name (e.g., "recv"); suffix auto-generated
typeData type label (e.g., "mutex", "rwlock", "socket"); stored and printed
fileSource file where registration occurred (typically FILE)
lineSource line where registration occurred (typically LINE)
funcFunction where registration occurred (typically func)
Returns
Pointer to the full registered name (e.g., "recv.7"), valid until unregister

The returned name string is stored in the registry and remains valid until named_unregister(key) is called. Do not modify or free the returned pointer.

The type parameter is stored in the registry and used by named_describe() to format output as "type: name (0xKEY) @ file:line:func()" automatically, without needing a type_hint parameter.

Multiple registrations of the same key will overwrite the previous entry. In release builds (NDEBUG), this is a no-op and returns base_name.

Definition at line 188 of file debug/named.c.

189 {
190#ifdef NDEBUG
191 // In release builds, skip debug registry and return the base name
192 return base_name ? base_name : "?";
193#endif
194
195 if (!base_name || !type || !format_spec) {
196 return "?";
197 }
198
199 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
200 return base_name;
201 }
202
203 // If parent_key provided, look up parent name and create hierarchical name
204 char final_base_name[256];
205 if (parent_key != 0) {
206 rwlock_rdlock(&g_named_registry.entries_lock);
207 const char *parent_name = named_lookup_name_unlocked(parent_key);
208 rwlock_rdunlock(&g_named_registry.entries_lock);
209
210 if (parent_name) {
211 snprintf(final_base_name, sizeof(final_base_name), "%s#%s", parent_name, base_name);
212 } else {
213 // Parent not found, fall back to base name
214 snprintf(final_base_name, sizeof(final_base_name), "%s", base_name);
215 }
216 } else {
217 snprintf(final_base_name, sizeof(final_base_name), "%s", base_name);
218 }
219
220 // Generate unique name using atomic counters (only for non-hierarchical names)
221 char name_buffer[256];
222 if (parent_key == 0) {
223 uint64_t counter = 0;
224 if (strcmp(type, "mutex") == 0) {
225 counter = __sync_fetch_and_add(&mutex_counter, 1);
226 } else if (strcmp(type, "rwlock") == 0) {
227 counter = __sync_fetch_and_add(&rwlock_counter, 1);
228 } else if (strcmp(type, "cond") == 0) {
229 counter = __sync_fetch_and_add(&cond_counter, 1);
230 } else if (strcmp(type, "atomic") == 0) {
231 counter = __sync_fetch_and_add(&atomic_counter, 1);
232 }
233 snprintf(name_buffer, sizeof(name_buffer), "%s.%" PRIu64, final_base_name, counter);
234 } else {
235 // Hierarchical names don't get counters - parent already has one
236 snprintf(name_buffer, sizeof(name_buffer), "%s", final_base_name);
237 }
238
239 // Allocate entry BEFORE acquiring lock (avoid long critical section)
240 named_entry_t *entry = malloc(sizeof(named_entry_t));
241 if (!entry)
242 return base_name;
243
244 entry->key = key;
245 entry->name = entry_strdup(name_buffer);
246 named_entry_init(entry, type, format_spec, file, line, func);
247
248 // Only hold lock for the hash table operation
249 log_dev("[NAMED_REGISTER_LOCK_1] About to acquire entries_lock for key=%p type=%s", (void *)key, type);
250 rwlock_wrlock(&g_named_registry.entries_lock);
251 HASH_ADD(hh, g_named_registry.entries, key, sizeof(uintptr_t), entry);
252 rwlock_wrunlock(&g_named_registry.entries_lock);
253 log_dev("[NAMED_REGISTER_LOCK_4] ✅ Released entries_lock");
254
255 return entry->name;
256}
unsigned long long uint64_t
Definition common.h:59
#define log_dev(...)
Log a DEV message (most verbose, development only)
Definition log/log.h:534
uintptr_t key
Definition debug/named.c:60

References named_registry_t::entries, named_registry_t::entries_lock, named_entry::key, named_registry_t::lifecycle, lifecycle_is_initialized(), log_dev, named_entry::name, rwlock_rdlock, rwlock_rdunlock, rwlock_wrlock, and rwlock_wrunlock.

◆ named_register_fd()

const char * named_register_fd ( int  fd,
const char *  name,
const char *  file,
int  line,
const char *  func 
)

#include <named.h>

Register a file descriptor with namespace encoding.

Parameters
fdFile descriptor value
fileSource file where registration occurred
lineSource line where registration occurred
funcFunction where registration occurred
Returns
Registered name string

Registers an FD with a key that includes type namespace to avoid collisions with packet types or other numeric values. If name is non-NULL, uses "name (fd=N)" format; otherwise auto-generates as "fd=N". In release builds (NDEBUG), this is a no-op and returns "fd=%d" string.

Definition at line 458 of file debug/named.c.

458 {
459 if (fd < 0) {
460 return "?";
461 }
462
463 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
464 return "?";
465 }
466
467 char name_buffer[256];
468 if (name) {
469 snprintf(name_buffer, sizeof(name_buffer), "%s", name);
470 } else {
471 snprintf(name_buffer, sizeof(name_buffer), "fd=%d", fd);
472 }
473
474 // Allocate entry BEFORE acquiring lock
475 named_entry_t *entry = malloc(sizeof(named_entry_t));
476 if (!entry)
477 return "?";
478
479 uintptr_t key = encode_fd_key(fd);
480 entry->key = key;
481 entry->name = entry_strdup(name_buffer);
482 named_entry_init(entry, "fd", "%d", file, line, func);
483
484 // Only hold lock for the hash table operation
485 rwlock_wrlock(&g_named_registry.entries_lock);
486 HASH_ADD(hh, g_named_registry.entries, key, sizeof(uintptr_t), entry);
487 rwlock_wrunlock(&g_named_registry.entries_lock);
488
489 return entry->name;
490}

References named_registry_t::entries, named_registry_t::entries_lock, named_entry::key, named_registry_t::lifecycle, lifecycle_is_initialized(), named_entry::name, rwlock_wrlock, and rwlock_wrunlock.

◆ named_register_fmt()

const char * named_register_fmt ( uintptr_t  key,
const char *  type,
const char *  format_spec,
const char *  file,
int  line,
const char *  func,
const char *  fmt,
  ... 
)

#include <named.h>

Register a resource with a formatted name, type, and location info (no auto-suffix)

Parameters
keyA uintptr_t representing the resource
typeData type label (e.g., "mutex", "socket"); stored and printed
fileSource file where registration occurred
lineSource line where registration occurred
funcFunction where registration occurred
fmtPrintf-style format string
...Format arguments
Returns
Pointer to the full registered name

Allows full control over the registered name. The format string and arguments are printed to create the name (e.g., "client.%u" with args "17" → "client.17"). No auto-suffix counter is applied.

The type parameter is stored in the registry and used by named_describe() for automatic formatting without needing type_hint.

In release builds (NDEBUG), this is a no-op and returns "?".

Definition at line 258 of file debug/named.c.

259 {
260 if (!type || !format_spec || !fmt) {
261 return "?";
262 }
263
264 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
265 return fmt;
266 }
267
268 // Format the name BEFORE acquiring lock
269 va_list args;
270 va_start(args, fmt);
271 char *full_name = NULL;
272 int ret = platform_vasprintf(&full_name, fmt, args);
273 va_end(args);
274
275 if (ret < 0) {
276 return "?";
277 }
278
279 // Allocate entry BEFORE acquiring lock
280 named_entry_t *entry = malloc(sizeof(named_entry_t));
281 if (!entry) {
282 free(full_name);
283 return "?";
284 }
285
286 // Initialize entry (name is pre-allocated as full_name)
287 entry->key = key;
288 entry->name = full_name;
289 named_entry_init(entry, type, format_spec, file, line, func);
290
291 // Only hold lock for the hash table operation
292 rwlock_wrlock(&g_named_registry.entries_lock);
293 HASH_ADD(hh, g_named_registry.entries, key, sizeof(uintptr_t), entry);
294 rwlock_wrunlock(&g_named_registry.entries_lock);
295
296 return entry->name;
297}
int platform_vasprintf(char **strp, const char *format, va_list ap)
Allocate formatted string with va_list (vasprintf replacement)
action_args_t args

References args, named_registry_t::entries, named_registry_t::entries_lock, named_entry::key, named_registry_t::lifecycle, lifecycle_is_initialized(), named_entry::name, platform_vasprintf(), rwlock_wrlock, and rwlock_wrunlock.

◆ named_register_packet_type()

const char * named_register_packet_type ( int  pkt_type,
const char *  file,
int  line,
const char *  func 
)

#include <named.h>

Register a packet type with namespace encoding.

Parameters
pkt_typePacket type value
fileSource file where registration occurred
lineSource line where registration occurred
funcFunction where registration occurred
Returns
Registered name string

Registers a packet type with a key that includes type namespace to avoid collisions with FDs or other numeric values. Name is auto-generated as "PACKET_TYPE=%d". In release builds (NDEBUG), this is a no-op and returns "PACKET_TYPE=%d" string.

Definition at line 526 of file debug/named.c.

526 {
527 if (pkt_type < 0) {
528 return "?";
529 }
530
531 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
532 return "?";
533 }
534
535 char name_buffer[256];
536 snprintf(name_buffer, sizeof(name_buffer), "PACKET_TYPE=%d", pkt_type);
537
538 // Allocate entry BEFORE acquiring lock
539 named_entry_t *entry = malloc(sizeof(named_entry_t));
540 if (!entry)
541 return "?";
542
543 uintptr_t key = encode_pkt_type_key(pkt_type);
544 entry->key = key;
545 entry->name = entry_strdup(name_buffer);
546 named_entry_init(entry, "packet_type", "%d", file, line, func);
547
548 // Only hold lock for the hash table operation
549 rwlock_wrlock(&g_named_registry.entries_lock);
550 HASH_ADD(hh, g_named_registry.entries, key, sizeof(uintptr_t), entry);
551 rwlock_wrunlock(&g_named_registry.entries_lock);
552
553 return entry->name;
554}

References named_registry_t::entries, named_registry_t::entries_lock, named_entry::key, named_registry_t::lifecycle, lifecycle_is_initialized(), named_entry::name, rwlock_wrlock, and rwlock_wrunlock.

◆ named_registry_for_each()

void named_registry_for_each ( named_iter_callback_t  callback,
void *  user_data 
)

#include <named.h>

Iterate through all registered entries.

Parameters
callbackFunction to call for each entry
user_dataOpaque context passed to callback

Safely iterates through all registered entries without holding the lock for the entire iteration (entries are copied). Callback is invoked for each entry. In release builds (NDEBUG), this is a no-op.

Definition at line 410 of file debug/named.c.

410 {
411 if (!callback || !lifecycle_is_initialized(&g_named_registry.lifecycle)) {
412 return;
413 }
414
415 // Snapshot entries while holding read lock
416 named_iter_entry_t entries[256];
417 int count = 0;
418
419 rwlock_rdlock(&g_named_registry.entries_lock);
420 for (named_entry_t *e = g_named_registry.entries; e != NULL && count < 256; e = e->hh.next) {
421 entries[count].key = e->key;
422 const char *src = e->name ? e->name : "?";
423 size_t src_len = strlen(src);
424 if (src_len >= MAX_NAME_LEN)
425 src_len = MAX_NAME_LEN - 1;
426 memcpy(entries[count].name, src, src_len);
427 entries[count].name[src_len] = '\0';
428 count++;
429 }
430 rwlock_rdunlock(&g_named_registry.entries_lock);
431
432 // Call callback outside the lock
433 for (int i = 0; i < count; i++) {
434 callback(entries[i].key, entries[i].name, user_data);
435 }
436}
#define MAX_NAME_LEN
Definition debug/named.c:31
uintptr_t key
char name[256]

References named_registry_t::entries, named_registry_t::entries_lock, named_iter_entry_t::key, named_registry_t::lifecycle, lifecycle_is_initialized(), MAX_NAME_LEN, named_iter_entry_t::name, rwlock_rdlock, and rwlock_rdunlock.

Referenced by debug_sync_check_cond_deadlocks(), and debug_sync_print_state().

◆ named_registry_register_packet_types()

void named_registry_register_packet_types ( void  )

#include <named.h>

Register all packet types from packet_type_t enum.

Registers all packet type enum values in the named registry using keys in the format "PACKET_TYPE=%d" where d is the enum value. This should be called once during initialization to enable packet type identification in log message formatting.

Definition at line 590 of file debug/named.c.

590 {
591 // No-op
592}

Referenced by main().

◆ named_unregister()

void named_unregister ( uintptr_t  key)

#include <named.h>

Unregister a resource by key.

Parameters
keyThe same uintptr_t passed to named_register

Removes the resource from the registry. Safe to call multiple times for the same key (idempotent).

Definition at line 299 of file debug/named.c.

299 {
300 if (!lifecycle_is_initialized(&g_named_registry.lifecycle)) {
301 return;
302 }
303
304 rwlock_wrlock(&g_named_registry.entries_lock);
305 named_entry_t *entry = NULL;
306 HASH_FIND(hh, g_named_registry.entries, &key, sizeof(uintptr_t), entry);
307 if (entry) {
308 HASH_DEL(g_named_registry.entries, entry);
309 free(entry->name);
310 if (entry->type)
311 free(entry->type);
312 if (entry->format_spec)
313 free(entry->format_spec);
314 if (entry->file)
315 free(entry->file);
316 if (entry->func)
317 free(entry->func);
318 free(entry);
319 }
320 rwlock_wrunlock(&g_named_registry.entries_lock);
321}

References named_registry_t::entries, named_registry_t::entries_lock, named_entry::file, named_entry::format_spec, named_entry::func, named_registry_t::lifecycle, lifecycle_is_initialized(), named_entry::name, rwlock_wrlock, rwlock_wrunlock, and named_entry::type.

◆ named_update_name()

const char * named_update_name ( uintptr_t  key,
const char *  new_base_name 
)

#include <named.h>

Update the registered name for a resource with a new base name.

Parameters
keyThe resource key
new_base_nameNew base name (will be auto-suffixed with counter)
Returns
Updated name string, or NULL if key not found

Updates an existing registration with a new base name. The new name will be auto-suffixed with a counter to make it unique (e.g., "client_123.0"). Useful when a resource gets an ID assigned after creation (e.g., client_id).

In release builds (NDEBUG), this is a no-op and returns NULL.

Definition at line 323 of file debug/named.c.

323 {
324 (void)key;
325 (void)new_base_name;
326 return NULL;
327}

Referenced by tcp_client_connect(), and websocket_client_connect().