• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 57bde3c9bda9cfdf1e55fd6ddc1c354bde1ee654 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Mon, 30 May 2022 17:54:18 +0100
4Subject: [PATCH 2/3] glocalfilemonitor: Skip event handling if the source has
5 been destroyed
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10This should prevent unbounded growth of the `event_queue` in the
11unlikely case that the `GSource` is removed from its `GMainContext` and
12destroyed separately from the `GFileMonitor`.
13
14I’m not sure if that can currently happen, but it could with future
15refactoring, so it’s best to address the possibility now while we’re
16thinking about this bit of code.
17
18Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
19
20Helps: #1941
21---
22 gio/glocalfilemonitor.c | 29 +++++++++++++++++++++++------
23 1 file changed, 23 insertions(+), 6 deletions(-)
24
25diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c
26index f408d0707..68afd7b51 100644
27--- a/gio/glocalfilemonitor.c
28+++ b/gio/glocalfilemonitor.c
29@@ -358,11 +358,28 @@ g_file_monitor_source_handle_event (GFileMonitorSource *fms,
30
31   g_mutex_lock (&fms->lock);
32
33-  /* NOTE: We process events even if the file monitor has already been disposed.
34-   *       The reason is that we must not take a reference to the instance here
35-   *       as destroying it from the event handling thread will lead to a
36-   *       deadlock when taking the lock in _ih_sub_cancel.
37+  /* NOTE:
38+   *
39+   * We process events even if the file monitor has already been disposed.
40+   * The reason is that we must not take a reference to the instance here as
41+   * destroying it from the event handling thread will lead to a deadlock when
42+   * taking the lock in _ih_sub_cancel.
43+   *
44+   * This results in seemingly-unbounded growth of the `event_queue` with the
45+   * calls to `g_file_monitor_source_queue_event()`. However, each of those sets
46+   * the ready time on the #GSource, which means that it will be dispatched in
47+   * a subsequent iteration of the #GMainContext it’s attached to. At that
48+   * point, `g_file_monitor_source_dispatch()` will return %FALSE, and this will
49+   * trigger finalisation of the source. That will clear the `event_queue`.
50+   *
51+   * If the source is no longer attached, this will return early to prevent
52+   * unbounded queueing.
53    */
54+  if (g_source_is_destroyed ((GSource *) fms))
55+    {
56+      g_mutex_unlock (&fms->lock);
57+      return TRUE;
58+    }
59
60   switch (event_type)
61     {
62@@ -595,9 +612,9 @@ g_file_monitor_source_dispose (GFileMonitorSource *fms)
63
64   g_file_monitor_source_update_ready_time (fms);
65
66-  g_mutex_unlock (&fms->lock);
67-
68   g_source_destroy ((GSource *) fms);
69+
70+  g_mutex_unlock (&fms->lock);
71 }
72
73 static void
74--
752.41.0.windows.3
76
77