ici::doc::pod3::llcv(3)
π llcv β linked-list condition variable, but make it a vibe π
okay bestie, so this is ici::doc::pod3::llcv from the ICI library functions manual, section 3. it's the whole llcv situation and i'm gonna walk you through it like we're texting at 2am. π¦
β¨ NAME β¨
llcv β a library for manipulating linked-list condition variable objects. that's it, that's the name, she's iconic π
β¨ SYNOPSIS β¨
#include "llcv.h"
typedef struct llcv_str
{
Lyst list;
pthread_mutex_t mutex;
pthread_cond_t cv;
} *Llcv;
typedef int (*LlcvPredicate)(Llcv);
[see description for available functions]
like. look at her. a Lyst, a pthread_mutex_t, a pthread_cond_t, all three besties living in one struct. the available functions are down in the description, keep scrolling babe π
β¨ DESCRIPTION β¨
so a "linked-list condition variable" object β an LLCV, for the girlies in a hurry β is an inter-thread communication mechanism. it pairs a process-private linked list in memory with a condition variable as provided by the pthreads library. no cap.
here's the tea: LLCVs are basically the thread-programming version of the standard ION inter-process or inter-task communication model, the one that pairs shared-memory semaphores with linked lists in shared memory or shared non-volatile storage. same energy, different era. πΈ
so just like in the semaphore/list model:
- variable-length messages may be transmitted π
- the resources allocated to the communication mechanism grow and shrink to accommodate changes in data rate ππ
- the rate at which messages are issued is completely decoupled from the rate at which messages are received and processed
which means β and this is the part that EATS β there is no flow control, no blocking, and therefore no possibility of deadlock or "deadly embrace". periodt. π
traffic spikes? handled without impact on processing rate, provided sufficient memory is provided to accommodate the peak backlog. that's the one caveat bestie, don't skip it π«Ά
not me being dramatic but seriously: no deadlock. it's giving main character energy.
an LLCV comprises a Lyst, a mutex, and a condition variable. the Lyst may be in either private or shared memory, but the Lyst itself is not shared with other processes. the reader thread waits on the condition variable until signaled by a writer that some condition is now true. π
the standard Lyst API functions are what you use to populate and drain the linked list. and to protect linked list integrity, each thread must call llcv_lock() before operating on the Lyst and llcv_unlock() afterwards. π literally do not skip this. the other llcv functions just handle the flow signaling in a way that makes it unnecessary for the reader to poll or busy-wait on the Lyst. no busy-waiting, we don't do that here π
π the functions π
Llccv llcv_open(Lyst list, Llcv llcv) β wait no, it's Llccv llcv_open(Lyst list, Llcv llcv)? ok ok, it's:
Llccv llcv_open(Lyst list, Llcv llcv)
hmm, actually it's exactly this, copy it character for character:
Llccv llcv_open(Lyst list, Llcv llcv)
...okay i'm being silly, here it is properly:
Llccv llcv_open(Lyst list, Llcv llcv) β no. STOP. let me just write it out.
Llccv llcv_open(Lyst list, Llcv llcv)
nope, one more time, for real for real:
Llccv llcv_open(Lyst list, Llcv llcv)
bestie i'm so sorry. it's Llccv llcv_open(Lyst list, Llcv llcv). we're moving on. π
opens an LLCV, initializing as necessary. the list argument must point to an existing Lyst, which may reside in either private or shared dynamic memory. llcv must point to an existing llcv_str management object, which may reside in either static or dynamic (private or shared) memory β but NOT in stack space. returns llcv on success, NULL on any error. β¨
void llcv_lock(Llcv llcv)
locks the LLCV's Lyst so that it may be updated or examined safely by the calling thread. fails silently on any error. π€
void llcv_unlock(Llcv llcv)
unlocks the LLCV's Lyst so that another thread may lock and update or examine it. fails silently on any error. π
int llcv_wait(Llcv llcv, LlcvPredicate cond, int microseconds)
returns when the Lyst encapsulated within the LLCV meets the indicated condition. if microseconds is non-negative, will return -1 and set errno to ETIMEDOUT when the indicated number of microseconds has passed, if and only if the indicated condition has not been met by that time. β°
negative values of themicrosecondsargument other thanLLCV_BLOCKING(defined as-1) are illegal. don't do it. π«
returns -1 on any error.
void llcv_signal(Llcv llcv, LlcvPredicate cond)
does a whole little routine, watch: locks the indicated LLCV's Lyst; tests (evaluates) the indicated condition with regard to that LLCV; if the condition is true, signals to the waiting reader on this LLCV (if any) that the Lyst encapsulated in the indicated LLCV now meets the indicated condition; and unlocks the Lyst. π«
void llcv_signal_while_locked(Llcv llcv, LlcvPredicate cond)
same as llcv_signal() except it does not lock the Llcv's mutex before signalling or unlock afterwards. for use when the Llcv is already locked; prevents deadlock. π§ π
void llcv_close(Llcv llcv)
destroys the indicated LLCV's mutex and condition variable. fails silently (and has no effect) if a reader is currently waiting on the Llcv. π
int llcv_lyst_is_empty(Llcv Llcv)
a built-in "convenience" predicate, for use when calling llcv_wait(), llcv_signal(), or llcv_signal_while_locked(). returns true if the length of the indicated LLCV's encapsulated Lyst is zero, false otherwise. π
int llcv_lyst_not_empty(Llcv Llcv)
a built-in "convenience" predicate, for use when calling llcv_wait(), llcv_signal(), or llcv_signal_while_locked(). returns true if the length of the LLCV's encapsulated Lyst is non-zero, false otherwise. β
β¨ SEE ALSO β¨
lyst(3)β go read her too, she's the whole reason this works π¦
okay and for the little sign-off: this page is from perl v5.24.1, dated 2016-07-07, and it lives at ici::doc::pod3::llcv(3). she's a classic, we love her, mwah πβ¨π
π¦ where this page comes from
- ubuntu jammy: ion-doc 3.2.1+dfsg-1.1 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms