iv_event_raw(3)
π iv_event_raw β bestie edition π
ok so this is a page from the ivykis programmer's manual (ivykis, that's the library, hi) and we're talking about iv_event_raw, which is lowkey the β¨cross-boundary queenβ¨ of event notification. Sit down, hydrate, let's go. π
πΈ NAME πΈ
IV_EVENT_RAW_INIT, iv_event_raw_register, iv_event_raw_unregister, iv_event_raw_post β manage ivykis objects for event notification. That's the whole job, and they do it flawlessly. π
π SYNOPSIS π
#include <iv_event_raw.h>
struct iv_event_raw {
void *cookie;
void (*handler)(void *);
};
void IV_EVENT_RAW_INIT(struct iv_event_raw *this);
int iv_event_raw_register(struct iv_event_raw *this);
void iv_event_raw_unregister(struct iv_event_raw *this);
void iv_event_raw_post(const struct iv_event_raw *this);
look at that struct. two fields. ->cookie and ->handler. minimal. iconic. no notes. π«Ά
π¦ DESCRIPTION π¦
so iv_event_raw gives you a whole way to deliver events to ivykis(3) recipients across thread and process boundaries. like, it does not care where you're calling from. it's that flexible. main character energy fr fr. π
Here's the flow, bestie, step by step:
- The intended event recipient calls
IV_EVENT_RAW_INITon astruct iv_event_rawobject. - Then it fills in
->cookieand->handler. - Then it calls
iv_event_raw_registeron that object.
and boom, you're set up. β¨
Now to actually generate an event? You call iv_event_raw_post on the previously initialized struct iv_event_raw object. What happens next is the moment: the callback specified by ->handler gets called in the thread that the struct iv_event_raw object was registered in, with ->cookie as its sole argument. that's it. one argument. no extra baggage. we love a clean interface. π
Wanna deinitialize a struct iv_event_raw object? Call iv_event_raw_unregister β and listen, this part matters β from the same thread that iv_event_raw_register was called from on that object. same thread, bestie. don't get cute with it. π¨
It is permitted to unregister a struct iv_event_raw object from any ivykis callback function in the thread it was registered in, including from a callback function triggered by this object. and yes, it is permitted to free the memory corresponding to an unregistered object from its own callback function. so you can absolutely unalive yourself in your own callback. it's fine. it's allowed. π
Now here's where it gets good. iv_event_raw_post can be called from:
- the same thread that
iv_event_raw_registerwas called from β - a different thread in the same process β
- or even a different process β
and β this is the part that makes people gasp β it can safely be called from signal handlers. not me being obsessed with a function that behaves itself inside a signal handler. ππ₯
PSA for the optimization girlies: if posting an event only ever needs to be done from within the same process, go look ativ_event(3)instead β it's a lighter-weight alternative toiv_event_raw. don't carry extra weight you don't need. β¨
Okay and now the behind-the-scenes lore, because i know you wanna know how she works internally. π§
Internally, iv_event_raw is implemented by registering a file descriptor (a struct iv_fd(3)) with the recipient thread's ivykis event loop, and by causing that file descriptor to become readable upon a call to iv_event_raw_post. yes. that's the trick. readable fd = event delivered. chef's kiss. π
And which fd, you ask? Well:
- If
eventfd(2)is available, it will be used to procure the abovementioned file descriptor. - If not,
iv_event_rawwill fall back topipe(2)as the source of its file descriptors.
eventfd(2) is preferred because it requires only one file descriptor table entry (while pipe(2) requires two), and it has much less kernel overhead than pipe(2) has. so like, fewer entries, less overhead, more slay. obviously we pick eventfd(2) when we can. π
β SEE ALSO β
go read them. iykyk. ππ
and that's the whole page, bestie. this one's from the ivykis manual, dated 2010-09-02 β yes she's been serving since 2010 and she has not missed once. πβ¨π periodt.
π¦ where this page comes from
- alpine 3.22: ivykis-doc 0.43.2-r0 Β· LGPL-2.1-or-later
- alpine 3.23: ivykis-doc 0.43.2-r0 Β· LGPL-2.1-or-later
- alpine 3.24: ivykis-doc 0.43.2-r0 Β· LGPL-2.1-or-later
- debian bookworm: libivykis-dev 0.42.4-1
- debian trixie: libivykis-dev 0.43.2-1+b1
- epel 10: ivykis-devel 0.43.2-2.el10_0 Β· LicenseRef-Callaway-LGPLv2+
- epel 9: ivykis-devel 0.42.4-7.el9 Β· LGPLv2+
- fedora 43: ivykis-devel 0.43.2-4.fc43 Β· LicenseRef-Callaway-LGPLv2+
- fedora 43: ivykis-devel 0.43.2-4.fc43 Β· LicenseRef-Callaway-LGPLv2+
- fedora 44: ivykis-devel 0.43.2-5.fc44 Β· LicenseRef-Callaway-LGPLv2+
- fedora 44: ivykis-devel 0.43.2-5.fc44 Β· LicenseRef-Callaway-LGPLv2+
- nixpkgs unstable: libivykis 0.43.2
- opensuse-leap 16.0: ivykis-devel 0.43-bp160.1.12 Β· LGPL-2.1-only
- opensuse-leap 16.0: ivykis-devel 0.43-bp160.1.12 Β· LGPL-2.1-only
- opensuse-leap 16.0: ivykis-devel 0.43-bp160.1.12 Β· LGPL-2.1-only
- opensuse-leap 16.0: ivykis-devel 0.43-bp160.1.12 Β· LGPL-2.1-only
- ubuntu jammy: libivykis-dev 0.42.4-1
- ubuntu noble: libivykis-dev 0.43-1build1
- ubuntu questing: libivykis-dev 0.43.2-1
- ubuntu resolute: libivykis-dev 0.43.2-1build1
- ubuntu stonking: libivykis-dev 0.43.2-1build1
- Copyright (C) 2010 Lennert Buytenhek
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms