1b5975d6bSopenharmony_ciFrom 1fc6a5c9b6a2b620ac4370d64c558f9b33aff063 Mon Sep 17 00:00:00 2001
2b5975d6bSopenharmony_ciFrom: Philip Withnall <pwithnall@endlessos.org>
3b5975d6bSopenharmony_ciDate: Mon, 30 May 2022 17:55:43 +0100
4b5975d6bSopenharmony_ciSubject: [PATCH 3/3] tests: Add a test for GFileMonitor deadlocks
5b5975d6bSopenharmony_ciMIME-Version: 1.0
6b5975d6bSopenharmony_ciContent-Type: text/plain; charset=UTF-8
7b5975d6bSopenharmony_ciContent-Transfer-Encoding: 8bit
8b5975d6bSopenharmony_ci
9b5975d6bSopenharmony_ciThis test is opportunistic in that it’s not possible to detect whether
10b5975d6bSopenharmony_cithe race condition has been hit (other than by hitting a deadlock).
11b5975d6bSopenharmony_ci
12b5975d6bSopenharmony_ciSo the only approach we can take for testing is to loop over the code
13b5975d6bSopenharmony_ciwhich has previously been known to cause a deadlock a number of times.
14b5975d6bSopenharmony_ci
15b5975d6bSopenharmony_ciThe number of repetitions is chosen from running the test with the
16b5975d6bSopenharmony_cideadlock fix reverted.
17b5975d6bSopenharmony_ci
18b5975d6bSopenharmony_ciSigned-off-by: Philip Withnall <pwithnall@endlessos.org>
19b5975d6bSopenharmony_ci
20b5975d6bSopenharmony_ciHelps: #1941
21b5975d6bSopenharmony_ci---
22b5975d6bSopenharmony_ci gio/tests/testfilemonitor.c | 52 +++++++++++++++++++++++++++++++++++++
23b5975d6bSopenharmony_ci 1 file changed, 52 insertions(+)
24b5975d6bSopenharmony_ci
25b5975d6bSopenharmony_cidiff --git a/gio/tests/testfilemonitor.c b/gio/tests/testfilemonitor.c
26b5975d6bSopenharmony_ciindex a47aeab38..082f0db26 100644
27b5975d6bSopenharmony_ci--- a/gio/tests/testfilemonitor.c
28b5975d6bSopenharmony_ci+++ b/gio/tests/testfilemonitor.c
29b5975d6bSopenharmony_ci@@ -1036,6 +1036,57 @@ test_file_hard_links (Fixture       *fixture,
30b5975d6bSopenharmony_ci   g_object_unref (data.output_stream);
31b5975d6bSopenharmony_ci }
32b5975d6bSopenharmony_ci 
33b5975d6bSopenharmony_ci+static void
34b5975d6bSopenharmony_ci+test_finalize_in_callback (Fixture       *fixture,
35b5975d6bSopenharmony_ci+                           gconstpointer  user_data)
36b5975d6bSopenharmony_ci+{
37b5975d6bSopenharmony_ci+  GFile *file = NULL;
38b5975d6bSopenharmony_ci+  guint i;
39b5975d6bSopenharmony_ci+
40b5975d6bSopenharmony_ci+  g_test_summary ("Test that finalization of a GFileMonitor in one of its "
41b5975d6bSopenharmony_ci+                  "callbacks doesn’t cause a deadlock.");
42b5975d6bSopenharmony_ci+  g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/1941");
43b5975d6bSopenharmony_ci+
44b5975d6bSopenharmony_ci+  file = g_file_get_child (fixture->tmp_dir, "race-file");
45b5975d6bSopenharmony_ci+
46b5975d6bSopenharmony_ci+  for (i = 0; i < 50; i++)
47b5975d6bSopenharmony_ci+    {
48b5975d6bSopenharmony_ci+      GFileMonitor *monitor = NULL;
49b5975d6bSopenharmony_ci+      GError *local_error = NULL;
50b5975d6bSopenharmony_ci+
51b5975d6bSopenharmony_ci+      /* Monitor the file. */
52b5975d6bSopenharmony_ci+      monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &local_error);
53b5975d6bSopenharmony_ci+      g_assert_no_error (local_error);
54b5975d6bSopenharmony_ci+      g_assert_nonnull (monitor);
55b5975d6bSopenharmony_ci+
56b5975d6bSopenharmony_ci+      /* Create the file. */
57b5975d6bSopenharmony_ci+      g_file_replace_contents (file, "hello", 5, NULL, FALSE,
58b5975d6bSopenharmony_ci+                               G_FILE_CREATE_NONE, NULL, NULL, &local_error);
59b5975d6bSopenharmony_ci+      g_assert_no_error (local_error);
60b5975d6bSopenharmony_ci+
61b5975d6bSopenharmony_ci+      /* Immediately drop the last ref to the monitor in the hope that this
62b5975d6bSopenharmony_ci+       * happens in the middle of the critical section in
63b5975d6bSopenharmony_ci+       * g_file_monitor_source_handle_event(), so that any cleanup at the end
64b5975d6bSopenharmony_ci+       * of that function is done with a now-finalised file monitor. */
65b5975d6bSopenharmony_ci+      g_object_unref (monitor);
66b5975d6bSopenharmony_ci+
67b5975d6bSopenharmony_ci+      /* Re-create the monitor and do the same again for deleting the file, to
68b5975d6bSopenharmony_ci+       * give a second chance at hitting the race condition. */
69b5975d6bSopenharmony_ci+      monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &local_error);
70b5975d6bSopenharmony_ci+      g_assert_no_error (local_error);
71b5975d6bSopenharmony_ci+      g_assert_nonnull (monitor);
72b5975d6bSopenharmony_ci+
73b5975d6bSopenharmony_ci+      /* Delete the file. */
74b5975d6bSopenharmony_ci+      g_file_delete (file, NULL, &local_error);
75b5975d6bSopenharmony_ci+      g_assert_no_error (local_error);
76b5975d6bSopenharmony_ci+
77b5975d6bSopenharmony_ci+      /* Drop the ref again. */
78b5975d6bSopenharmony_ci+      g_object_unref (monitor);
79b5975d6bSopenharmony_ci+    }
80b5975d6bSopenharmony_ci+
81b5975d6bSopenharmony_ci+  g_object_unref (file);
82b5975d6bSopenharmony_ci+}
83b5975d6bSopenharmony_ci+
84b5975d6bSopenharmony_ci int
85b5975d6bSopenharmony_ci main (int argc, char *argv[])
86b5975d6bSopenharmony_ci {
87b5975d6bSopenharmony_ci@@ -1047,6 +1098,7 @@ main (int argc, char *argv[])
88b5975d6bSopenharmony_ci   g_test_add ("/monitor/dir-not-existent", Fixture, NULL, setup, test_dir_non_existent, teardown);
89b5975d6bSopenharmony_ci   g_test_add ("/monitor/cross-dir-moves", Fixture, NULL, setup, test_cross_dir_moves, teardown);
90b5975d6bSopenharmony_ci   g_test_add ("/monitor/file/hard-links", Fixture, NULL, setup, test_file_hard_links, teardown);
91b5975d6bSopenharmony_ci+  g_test_add ("/monitor/finalize-in-callback", Fixture, NULL, setup, test_finalize_in_callback, teardown);
92b5975d6bSopenharmony_ci 
93b5975d6bSopenharmony_ci   return g_test_run ();
94b5975d6bSopenharmony_ci }
95b5975d6bSopenharmony_ci-- 
96b5975d6bSopenharmony_ci2.41.0.windows.3
97b5975d6bSopenharmony_ci
98