iv_work(3)
π iv_work β ivykis worker thread management π
okay bestie, so this is iv_work, part of the ivykis programmer's manual, and it's literally the page about making your threads do the heavy lifting so your event loop stays pretty and unbothered. π§β¨
It's giving: the functions IV_WORK_POOL_INIT, iv_work_pool_create, iv_work_pool_put, IV_WORK_ITEM_INIT, iv_work_pool_submit_work, and iv_work_pool_submit_continuation. All of them. Together. As a girl gang. π
β¨ SYNOPSIS β¨
#include <iv_work.h>
struct iv_work_pool {
int max_threads;
void *cookie;
void (*thread_start)(void *cookie);
void (*thread_stop)(void *cookie);
};
struct iv_work_item {
void *cookie;
void (*work)(void *cookie);
void (*completion)(void *cookie);
};
void IV_WORK_POOL_INIT(struct iv_work_pool *this);
int iv_work_pool_create(struct iv_work_pool *this);
int iv_work_pool_put(struct iv_work_pool *this);
void IV_WORK_ITEM_INIT(struct iv_work_item *work);
int iv_work_pool_submit_work(struct iv_work_pool *this, struct
iv_work_item *work);
int iv_work_pool_submit_continuation(struct iv_work_pool *this, struct
iv_work_item *work);
like. look at that struct. two structs, six functions, one header. clean. minimal. iconic. π
πΈ DESCRIPTION πΈ
π«Ά making a pool
So here's the tea: you call iv_work_pool_create on a struct iv_work_pool object that you already initialised with IV_WORK_POOL_INIT, and boom β you've got yourself a pool of worker threads. β¨
What's it for? Two things, and they're both lowkey important:
- offloading CPU intensive tasks to it, so those tasks don't go and negatively influence event handling latency in the calling thread (rude of them tbh)
- enabling the use of multiple host CPUs for those CPU intensive tasks, because one core is not the moment
iv_work dynamically adjusts the number of threads in the pool to the amount of work there is to do. it's very self-aware, very adaptive, main character energy. π¦
The ->max_threads member of struct iv_work_pool specifies the maximum number of threads that will be created in this pool. that's the ceiling, bestie. don't expect more.
π submitting work
Calling iv_work_pool_submit_work on a struct iv_work_item object previously initialised by IV_WORK_ITEM_INIT submits a work item to a pool. so cute, so efficient. π
Here's the breakdown:
->workmember ofstruct iv_work_itemβ the function that gets called in one of the worker threads in the pool specified by->this, with->cookieas its sole argument- when the work function has completed,
iv_workwill call the->completioncallback to indicate this β also with->cookieas its sole argument β in the thread thativ_work_pool_createwas called in for this pool object
so the work runs over there, the completion comes back here. it's giving boomerang. πͺ
π continuations (the from-inside-a-worker special)
Calling iv_work_pool_submit_continuation from a worker thread allows submitting a work item similarly to iv_work_pool_submit_work. but here's the plot twist:
iv_work_pool_submit_workcan only be called from the thread owningiv_workiv_work_pool_submit_continuationcan be called from any of the worker threads
The ->completion callback of these jobs will be executed from the thread owning iv_work. so it always comes home. π
β the NULL special case
As a special case, calling iv_work_pool_submit_work with a NULL work pool pointer will cause the work item to be processed in the local thread, from an iv_task(3) callback. no pool? no problem. still slays. π₯
π§ thread_start and thread_stop
If the ->thread_start function pointer specified in struct iv_work_pool is not NULL, it will be called upon creation of a new worker thread, in the context of the created worker thread, with ->cookie as its sole argument.
β οΈ Calls to ->thread_start are not explicitly serialised, which should be kept in mind when manipulating state shared between threads from within that callback function. bestie please be careful, that's a race condition waiting to happen. π
Similarly, if iv_work decides to terminate a worker thread β for example due to inactivity β ->thread_stop will be called in the context of the terminating thread, with ->cookie as its sole argument.
β οΈ Calls to ->thread_stop are also not explicitly serialised. same warning, same energy, same "please lock your stuff". π
π the rules, the boundaries, the law
iv_work_pool_submit_workcan only be called from the thread thativ_work_pool_createfor this pool object was called in.iv_work_pool_submit_continuationcan called from any of the worker threads.- There is no way to cancel submitted work items. once it's submitted, it's submitted. no take-backs. periodt. π
- There is no guaranteed order, FIFO or otherwise, between different work items submitted to the same worker thread pool. it's giving chaos but make it scheduled. π
π putting the pool down
When the user has no more work items to submit to the pool, its reference to the pool can be dropped by calling iv_work_pool_put.
And now the important bit, so listen up:
If there are still pending or running work items assigned to this pool when iv_work_pool_put is called, those work items will not be canceled. they will be allowed to run to completion, and their ->completion callbacks will be called as usual. π«Ά
A similar thing holds for the ->thread_start and ->thread_stop callbacks β they can also still be called after iv_work_pool_put returns.
π Even so, the memory corresponding to thestruct iv_work_poolcan immediately be freed or reused by the user upon return of theiv_work_pool_putcall. yes, immediately. yes, while those callbacks are still out there living their lives. mind the lifetime, bestie, it's the whole game.
π internal tea
Internally, iv_work uses iv_thread(3) for its thread management. iykyk. π
π SEE ALSO π
and that's the whole page, bestie!! πβ¨πΈ this one came from the ivykis manual, dated 2010-09-14, and it lives at section iv_work(3). go forth and thread responsibly π¦π π
π¦ 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 trixie: libivykis-dev 0.43.2-1+b1
- epel 10: ivykis-devel 0.43.2-2.el10_0 Β· LicenseRef-Callaway-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 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