It seems Jammy is also affected (per the vibe-coded reproducer); adding
it to the bug now.
** Also affects: glib2.0 (Ubuntu Jammy)
Importance: Undecided
Status: New
** Changed in: glib2.0 (Ubuntu Jammy)
Status: New => In Progress
** Changed in: glib2.0 (Ubuntu Jammy)
Assignee: (unassigned) => Alex Ramirez (kicchou)
** Changed in: glib2.0 (Ubuntu Jammy)
Milestone: None => jammy-updates
** Changed in: glib2.0 (Ubuntu Noble)
Importance: Undecided => Medium
** Changed in: glib2.0 (Ubuntu Jammy)
Importance: Undecided => Low
** Description changed:
[ Impact ]
Corporate users of the Evolution mail client are running into the
program getting 'stuck' when performing refreshes on many folders at
once.
This occurs because `glib2.0`'s `GTask` is prone to livelocking,
becoming unable to grow the thread pool when it is exhausted. Evolution
can quickly occupy every thread in the pool on refresh operations,
triggering the issue.
A fix has been committed upstream that provisions an extra thread in the
pool, enabling an existing underlying watchdog to always be able to grow
the pool when needed.
[ Test plan ]
A vibe-coded reproducer program (`gtask-pool-latch-repro.c`) is attached
to this bug report. The test plan involves compiling and running it to
observe its output.
# Download dependencies
- 0. Get a fresh Noble machine
+ 0. Get a fresh Jammy or Noble machine
1. sudo apt install libglib2.0-dev build-essential curl
2. curl https://launchpadlibrarian.net/875318806/gtask-pool-latch-repro.c
--remote-name
# Build and run reproducer
3. gcc -O0 -g -o gtask-pool-latch-repro gtask-pool-latch-repro.c $(pkg-config
--cflags --libs gio-2.0)
4. ./gtask-pool-latch-repro
# Reproducer output
5a. Unpatched glib2.0 reproducer output (fail)
```
ubuntu@noble-vm:~/glibrepro$ ./gtask-pool-latch-repro
glib 2.80.0 (compiled against 2.80.0) mode=DEADLOCK
16 tasks running (pool grew via the watchdog)
... inner sub-task still queued after 5s (gtask.c promises pool growth
within ~1s)
... inner sub-task still queued after 10s (gtask.c promises pool growth
within ~1s)
... inner sub-task still queued after 15s (gtask.c promises pool growth
within ~1s)
... inner sub-task still queued after 20s (gtask.c promises pool growth
within ~1s)
... inner sub-task still queued after 25s (gtask.c promises pool growth
within ~1s)
... inner sub-task still queued after 30s (gtask.c promises pool growth
within ~1s)
DEADLOCK: inner sub-task never started after 30s.
The GTask pool watchdog is disarmed (it only arms when a task
starts, never when one is queued) - the queued sub-task can only
run if one of the 16 blocked tasks completes, and the task they
are all blocked on is the queued one.
ubuntu@noble-vm:~/glibrepro$
```
5b. Patched glib2.0 reproducer output (success)
```
ubuntu@noble-vm:~/glibrepro$ ./gtask-pool-latch-repro
glib 2.80.0 (compiled against 2.80.0) mode=DEADLOCK
16 tasks running (pool grew via the watchdog)
inner sub-task RAN (~1000 ms after push): pool recovered [bug NOT reproduced
this run]
ubuntu@noble-vm:~/glibrepro$
```
[ Where problems could occur ]
This patch modifies the cleanup path of a GTask. Regression risks
include introducing new memory leaks or other memory errors such as use-
after-free vulnerabilities. In other words, resources that were being
cleaned up correctly would now fail to be cleaned up correctly in the
case of a regression.
The patch has been merged upstream for over 9 months. No regressions
have since been reported upstream or in newer releases of Ubuntu.
[ Other info ]
Upstream commit: https://gitlab.gnome.org/GNOME/glib/-/commit/7e30869
Upstream bug report: https://gitlab.gnome.org/GNOME/glib/-/work_items/3840
Thank you Benjamin Herrenschmidt for your work on this bug report!
[ Original bug ]
Please consider backporting
https://gitlab.gnome.org/GNOME/glib/-/commit/7e30869 to Ubuntu 24.04
glib2
I finally tracked down why evolution (with EWS backend in my case) ends
up with a bunch of deadlocked jobs making no forward progress when it
tries to refresh too many folders at once.
It boils down to evo exhausing glib2's GTask pool, and the underlying
GTask watchdog for growing the pool not working properly. The above
upstream commit fixes the latter.
Here's a more detailed description from my artifical buddy:
Evolution's mail sync jobs can occupy every thread in GIO's shared GTask
pool while blocked on a common connection lock; the lock holder then
performs a synchronous TLS handshake (glib-networking's
g_tls_connection_base_handshake()), whose handshake worker is itself
queued as a GTask on that same exhausted pool — and because gtask.c's
pool-growing watchdog is left disarmed at that point (glib 2.80's
g_task_thread_cleanup() shrinks the pool's max threads on every
completion and nothing re-arms the watchdog when a task is merely
queued), the handshake task never runs, deadlocking the account
permanently; fixed upstream by commit 7e30869 ("gtask: fix
g_task_run_in_thread", issue #3840), which keeps one thread of headroom,
but that fix is absent from the glib-2-80 series shipped in noble.
ProblemType: Bug
DistroRelease: Ubuntu 24.04
Package: libglib2.0-0t64 2.80.0-6ubuntu3.8
ProcVersionSignature: Ubuntu 7.0.0-28.28~24.04.1-generic 7.0.12
Uname: Linux 7.0.0-28-generic x86_64
ApportVersion: 2.28.3-0ubuntu0.1
Architecture: amd64
CasperMD5CheckResult: unknown
CurrentDesktop: ubuntu:GNOME
Date: Mon Aug 31 14:44:13 2026
ProcEnviron:
LANG=en_US.UTF-8
PATH=(custom, no user)
SHELL=/bin/bash
TERM=xterm-256color
XDG_RUNTIME_DIR=<set>
RebootRequiredPkgs: Error: path contained symlinks.
SourcePackage: glib2.0
UpgradeStatus: No upgrade log present (probably fresh install)
--
You received this bug notification because you are a member of Ubuntu
Desktop Bugs, which is subscribed to glib2.0 in Ubuntu.
https://bugs.launchpad.net/bugs/2165869
Title:
glib2 GTask bug causes livelocks in Evolution (and others)
To manage notifications about this bug go to:
https://bugs.launchpad.net/glib/+bug/2165869/+subscriptions
--
desktop-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/desktop-bugs