io_getevents(3)

io_getevents(3) β€” Linux AIO πŸ’–

okay bestie, gather round, because we are reading events off an AIO completion queue and honestly? it's giving ✨main character✨. this is the io_getevents(3) and aio_pgetevents page, straight out of the Linux AIO manual, and i'm gonna walk you through it like we're texting at 2am 🫢


✨ NAME ✨

io_getevents, aio_pgetevents β€” read resulting events from io requests πŸŽ€

no cap, that's the whole job. you did a bunch of async io, now you wanna know what came back.


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <errno.h>

#include <libaio.h>

struct iocb {
     void      *data;
     unsigned  key;
     short          aio_lio_opcode;
     short          aio_reqprio;
     int       aio_fildes;
};

struct io_event {
        unsigned        PADDED(data, __pad1);
        unsigned        PADDED(obj,  __pad2);
        unsigned        PADDED(res,  __pad3);
        unsigned        PADDED(res2, __pad4);
};

int io_getevents(io_context_t ctx, long nr, struct io_event *events[], struct timespec *timeout);
int io_pgetevents(io_context_t ctx, long nr, struct io_event *events[], struct timespec *timeout, sigset_t *sigmask);

copy those structs exactly, bestie, i am not playing with you β€” PADDED and all, character for character. πŸ’…


🌸 DESCRIPTION 🌸

so what it does: it attempts to read up to nr events from the completion queue for the aio_context specified by ctx. that's it. that's the vibe check. you hand it a context, you tell it how many events you want max, and it fishes them out of the completion queue for you πŸ“


πŸ‘‘ RETURN VALUES πŸ‘‘

it may return 0 if no events are available and the timeout specified by when has elapsed β€” and heads up, when == NULL specifies an infinite timeout, so like, it will simply wait forever, bestie 😭

also important: the timeout pointed to by when is relative and will be updated if it's not NULL and the operation blocks. so don't be surprised when your timespec comes back different, it's not gaslighting you, that's documented ✨

and it will fail with ENOSYS if it's not implemented. rude, but okay πŸ’€

🌈 io_pgetevents() 🌈

the relationship between io_getevents() and io_pgetevents() is analogous to the relationship between select(2) and pselect(2). and similar to pselect(2), pgetevents() lets an application safely wait until either an aio completion event happens or until a signal is caught πŸ‘‘

the following io_pgetevents() call:

ret = io_pgetevents(ctx, min_nr, nr, events, timeout, sigmask);

is equivalent to atomically executing the following calls:

sigset_t origmask;

pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ret = io_getevents(ctx, min_nr, nr, events, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);

see the description of pselect(2) for an explanation of why io_pgetevents() is necessary. (iykyk 🧚)

if the sigmask argument is specified as NULL, then no signal mask manipulation is performed β€” and thus io_pgetevents() behaves the same as io_getevents(). same girl, different font πŸ’…


πŸ’€ ERRORS πŸ’€

  • EINVAL β€” if ctx is invalid, if min_nr is out of range, if nr is out of range, if when is out of range. so many ranges, so little time πŸ™ˆ
  • EFAULT β€” if any of the memory specified to is invalid.

πŸ’œ SEE ALSO πŸ’œ


that's the whole page, bestie. go read your events. slay. periodt. πŸ’…βœ¨

this one's from Linux, dated 2019-07-23, and it lives at section io_getevents(3) β€” mwah, love u, bye πŸ«ΆπŸŽ€