LC_CHANN...K_HANDLER(3)
π lc_channel_nack_handler, lc_channel_nack_handler_thr, lc_channel_nack_add_log β it's giving "outgoing message logging so we can handle NACK and replay requests" β¨
okay bestie, this is a page from the Librecast Programmer's Manual, and it's literally the lore on how your channel keeps receipts of what it sent so it can resend stuff when someone yells at it. no cap.
π LIBRARY
Librecast library (liblibrecast, -llibrecast) π¦
β¨ SYNOPSIS
#include <librecast/net.h>
int lc_channel_nack_handler(lc_channel_t *chan, int n_seconds);
int lc_channel_nack_handler_thr(lc_channel_t *chan, int n_seconds, void *(*nack_thread)(void *));
int lc_channel_nack_add_log(lc_channel_t *chan, const void *buf, size_t len, lc_seq_t seq);
Compile and link with -llibrecast. π«Ά
πΈ DESCRIPTION
lc_channel_nack_handler() sets up a per-channel buffer that keeps a copy of all the outgoing messages you sent via lc_msg_send(), and it also spins up a whole new thread (affectionately called the "nack thread") to handle any retransmission requests. those outgoing messages stick around for at least n_seconds seconds β that is, if there's enough free memory lying around to do it. the nack thread listens for messages on a related channel, reads them as NACK messages, and arranges for the corresponding messages to get retransmitted. the normal scenario? those NACK messages get generated when you call lc_channel_detect_gaps() on the receiver side. and btw, calling lc_channel_free(3) will stop the nack thread if it's running. periodt. π
lc_channel_nack_handler_thr() is basically lc_channel_nack_handler()'s twin, except you get to specify a different function to use for the nack thread. it gets called in a new thread with an opened channel and socket where it can receive NACK messages, plus another channel it can use to resend packets. ngl, currently there is no alternative thread to use, and this function is only used by the library's tests. however, a different nack thread could totally be provided in future β for example, to deal with the special case of messages sent from static data, which can be resent without storing recent messages in a memory buffer. iconic foreshadowing fr fr. π₯
lc_channel_nack_add_log() adds a message to the internal memory buffer, making it available for retransmission as the result of a NACK. lowkey you don't normally need to call this function if all your messages go out using lc_msg_send(). BUT β and this is the important part, bestie β an application that defines its own message format will need to call lc_channel_nack_add_log() with a copy of each message as it goes on the wire, and the sequence number it contains, because the library will have absolutely no way to find this info in the application's own message format. π
π¨ also: the application needs to calllc_channel_nack_handler()before usinglc_channel_nack_add_log(), otherwise the call will not log anything at all. this is actually useful if message logging and NACK request handling are optional β your app can conditionally calllc_channel_nack_handler()during initialisation, but then unconditionally calllc_channel_nack_add_log()for every message it sends. main character energy tbh. π
π RETURN VALUE
lc_channel_nack_handler() and lc_channel_nack_handler_thr() return 0 on success, and -1 to indicate an error β setting the global variable errno to an appropriate code, most likely ENOMEM, to say that there wasn't enough memory to set up the required data structures. π
the lc_channel_nack_add_log() function returns 0 on success and -1 to indicate that there was no memory to store the message in its internal buffers, setting errno to the value ENOMEM. π
π¦ ERRORS
lc_channel_nack_handler() and lc_channel_nack_handler_thr() can fail with any of the errors the malloc() library function can produce, as well as any errors produced by the lc_channel_sidehash() or lc_socket_new() functions.
lc_channel_nack_add_log() can fail with any of the errors the malloc() library function can produce.
π EXAMPLE
β Program source
lc_ctx_t *lctx;
lc_channel_t *chan;
lctx = lc_ctx_new();
chan = lc_channel_new(lctx, "channel name");
if (lc_channel_nack_handler(chan, 10) == -1) {
/* handle this error */
}
/* your program goes here, likely calling lc_msg_send(chan, ...) */
lc_channel_free(chan);
lc_ctx_free(lctx);
π SEE ALSO
lc_channel_detect_gaps(3)lc_channel_free(3)lc_msg_send(3)
and that's the whole vibe, bestie β this page is LIBRECAST, dated 2022-10-29, and yeah it's technically titled LC_CHANN...K_HANDLER(3) because even manpage titles gotta abbreviate sometimes. slay. πβ¨π
π¦ where this page comes from
- debian trixie: liblibrecast-dev 0.9.1-1 Β· GPL-2.0-only OR GPL-3.0-only
- nixos 26.05: librecast 0.11.2
- nixpkgs unstable: librecast 0.11.2
- ubuntu noble: liblibrecast-dev 0.8.0-1.1build1 Β· GPL-2.0-only OR GPL-3.0-only
- ubuntu questing: liblibrecast-dev 0.9.1-1
- ubuntu resolute: liblibrecast-dev 0.11.2-2 Β· GPL-2.0-only OR GPL-3.0-only
- ubuntu stonking: liblibrecast-dev 0.11.2-2build1 Β· GPL-2.0-only OR GPL-3.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms