** 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`'s `GTask` is prone to livelocking when its
+ thread pool is exhausted. Evolution can quickly occupy every thread in
+ the pool on refresh operations, exacerbating the issue.
+ 
+ A fix has been committed upstream that always provisions an extra thread
+ in the pool, enabling an 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
+ 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 g_task. Regression risks
+ include introducing new memory leaks or other memory errors such as use-
+ after-free vulnerabilities.
+ 
+ However, the patch has been merged upstream for over 9 months and no
+ regressions have since been reported.
+ 
+ [ 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>
+  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)
- 
- Here's the SRU template:
- 
- [Impact]
- * Evolution livelocks trying to perform too many tasks at once. This bug 
probably affects a number of other glib users.
- * This is causing significant headaches for corporate users of evo with 
evolution-ews
- 
- [Test Plan]
- * It can generally be reproduced by triggering enough simultanous tasks in 
evolution but it's difficult to provide step-by-step instructions. i have 
attached an AI generated reproducer however that reproduces the same condition.
- * The patch is upstream. It fixes the problem by ensuring that at least one 
spare GTask is always available.
- 
- [Where problems could occur]
- * I can't think of anything
- * The patch modifies the localized cleanup path of a gtask in a rather 
straightforward way and has been upstream in glib2 for almost a year now.
- 
- [Other Info]
- * Upstream: https://gitlab.gnome.org/GNOME/glib/-/commit/7e30869

** 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`'s `GTask` is prone to livelocking when its
- thread pool is exhausted. Evolution can quickly occupy every thread in
- the pool on refresh operations, exacerbating the issue.
+ This occurs because `glib2.0`'s `g_task` 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,
+ exacerbating the issue.
  
  A fix has been committed upstream that always provisions an extra thread
- in the pool, enabling an underlying watchdog to always be able to grow
- the pool when needed.
+ 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
  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 g_task. Regression risks
  include introducing new memory leaks or other memory errors such as use-
  after-free vulnerabilities.
  
  However, the patch has been merged upstream for over 9 months and no
  regressions have since been reported.
  
  [ 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)

** 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 `g_task` is prone to livelocking,
+ 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,
  exacerbating the issue.
  
  A fix has been committed upstream that always 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
  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)
+   ... 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 g_task. Regression risks
  include introducing new memory leaks or other memory errors such as use-
  after-free vulnerabilities.
  
  However, the patch has been merged upstream for over 9 months and no
  regressions have since been reported.
  
  [ 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>
+  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)

** 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,
- exacerbating the issue.
+ triggering the issue.
  
- A fix has been committed upstream that always provisions an extra thread
- in the pool, enabling an existing underlying watchdog to always be able
- to grow the pool when needed.
+ 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
  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 g_task. Regression risks
  include introducing new memory leaks or other memory errors such as use-
  after-free vulnerabilities.
  
  However, the patch has been merged upstream for over 9 months and no
  regressions have since been reported.
  
  [ 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)

** 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
  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 g_task. Regression risks
+ 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.
  
  However, the patch has been merged upstream for over 9 months and no
  regressions have since been reported.
  
  [ 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

Reply via email to