-
Pl
chevron_right
Christian Hergert: Libdex Improvements
news.movim.eu / PlanetGnome • 12 hours ago • 2 minutes
libdex 1.2 is still in pre-alpha phase but it is also far enough along that it is worth talking about the direction: libdex is growing from a library of future and fiber helpers into a more complete concurrency toolkit.
The most important 1.2 theme is that applications can now describe not just what work should happen concurrently, but how that work should be bounded and owned.
DexLimiter
lets a workload run with a fixed concurrency budget, with
dex_limiter_run()
handling the common fiber case by acquiring a permit before work starts and releasing it after the fiber completes. For larger workflows,
DexTaskGroup
gives related futures a structured scope that can be closed, awaited, or cancelled as one unit.
That combination makes cleanup much easier to reason about when a workflow has many moving pieces. A loader can start many subtasks, keep only a useful number active at once, and return a single future representing the whole operation. If the window closes, the project changes, or the operation times out, the group gives the application one place to cleanly shut the work down.
static DexFuture *
load_many_files (GPtrArray *files)
{
g_autoptr(DexTaskGroup) group = dex_task_group_new (0);
g_autoptr(DexLimiter) limiter = dex_limiter_new (8);
for (guint i = 0; i < files->len; i++)
{
GFile *file = g_ptr_array_index (files, i);
dex_task_group_add (group,
dex_limiter_run (limiter,
NULL,
0,
load_one_file,
g_object_ref (file),
g_object_unref));
}
return dex_future_with_timeout_seconds (dex_task_group_close (group), 10);
}
There is also a new
DexThreadPool
for the cases that are not naturally fiber-shaped. Fibers and schedulers are still the right fit for cooperative async work, but many applications need to integrate blocking libraries, database clients, filesystem helpers, or other foreign code. A fixed pool of reusable OS threads,
dex_thread_pool_submit()
, and asynchronous
dex_thread_pool_close()
give that integration story a bounded queue and an explicit shutdown path.
Deadlines are another practical piece of the same story. The new timeout wrappers, including
dex_future_with_timeout_seconds()
and
dex_future_with_deadline()
, turn time limits into ordinary future composition. Instead of open-coded timeout state spread across an application, a future can resolve normally, reject normally, or reject with
DEX_ERROR_TIMED_OUT
when the deadline wins.
On the I/O side, 1.2 continues filling in the operations that make responsiveness easier to preserve.
dex_aio_open()
and
dex_aio_close()
matter because even operations that look small can stall when they touch the kernel, storage, or network-backed filesystems. Keeping those calls in libdex’s
file-descriptor AIO model
makes it easier to keep them off the UI thread, using
io_uring
where it is available and the fallback AIO backend elsewhere.
The broader
GIO coverage
is intentionally less surprising, but still important. More app launching,
GFile
, stream, socket, resolver, proxy, TLS, DTLS, permission, subprocess, and Unix-facing APIs now have future-first wrappers. That is the kind of coverage people should expect from libdex over time: not every wrapper needs a release headline, but each one reduces the pressure to leave the future model for common GNOME application work.