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