98 lines
3.4 KiB
Diff
98 lines
3.4 KiB
Diff
|
|
From 1fc6a5c9b6a2b620ac4370d64c558f9b33aff063 Mon Sep 17 00:00:00 2001
|
|||
|
|
From: Philip Withnall <pwithnall@endlessos.org>
|
|||
|
|
Date: Mon, 30 May 2022 17:55:43 +0100
|
|||
|
|
Subject: [PATCH 3/3] tests: Add a test for GFileMonitor deadlocks
|
|||
|
|
MIME-Version: 1.0
|
|||
|
|
Content-Type: text/plain; charset=UTF-8
|
|||
|
|
Content-Transfer-Encoding: 8bit
|
|||
|
|
|
|||
|
|
This test is opportunistic in that it’s not possible to detect whether
|
|||
|
|
the race condition has been hit (other than by hitting a deadlock).
|
|||
|
|
|
|||
|
|
So the only approach we can take for testing is to loop over the code
|
|||
|
|
which has previously been known to cause a deadlock a number of times.
|
|||
|
|
|
|||
|
|
The number of repetitions is chosen from running the test with the
|
|||
|
|
deadlock fix reverted.
|
|||
|
|
|
|||
|
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
|||
|
|
|
|||
|
|
Helps: #1941
|
|||
|
|
---
|
|||
|
|
gio/tests/testfilemonitor.c | 52 +++++++++++++++++++++++++++++++++++++
|
|||
|
|
1 file changed, 52 insertions(+)
|
|||
|
|
|
|||
|
|
diff --git a/gio/tests/testfilemonitor.c b/gio/tests/testfilemonitor.c
|
|||
|
|
index a47aeab38..082f0db26 100644
|
|||
|
|
--- a/gio/tests/testfilemonitor.c
|
|||
|
|
+++ b/gio/tests/testfilemonitor.c
|
|||
|
|
@@ -1036,6 +1036,57 @@ test_file_hard_links (Fixture *fixture,
|
|||
|
|
g_object_unref (data.output_stream);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+static void
|
|||
|
|
+test_finalize_in_callback (Fixture *fixture,
|
|||
|
|
+ gconstpointer user_data)
|
|||
|
|
+{
|
|||
|
|
+ GFile *file = NULL;
|
|||
|
|
+ guint i;
|
|||
|
|
+
|
|||
|
|
+ g_test_summary ("Test that finalization of a GFileMonitor in one of its "
|
|||
|
|
+ "callbacks doesn’t cause a deadlock.");
|
|||
|
|
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/1941");
|
|||
|
|
+
|
|||
|
|
+ file = g_file_get_child (fixture->tmp_dir, "race-file");
|
|||
|
|
+
|
|||
|
|
+ for (i = 0; i < 50; i++)
|
|||
|
|
+ {
|
|||
|
|
+ GFileMonitor *monitor = NULL;
|
|||
|
|
+ GError *local_error = NULL;
|
|||
|
|
+
|
|||
|
|
+ /* Monitor the file. */
|
|||
|
|
+ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &local_error);
|
|||
|
|
+ g_assert_no_error (local_error);
|
|||
|
|
+ g_assert_nonnull (monitor);
|
|||
|
|
+
|
|||
|
|
+ /* Create the file. */
|
|||
|
|
+ g_file_replace_contents (file, "hello", 5, NULL, FALSE,
|
|||
|
|
+ G_FILE_CREATE_NONE, NULL, NULL, &local_error);
|
|||
|
|
+ g_assert_no_error (local_error);
|
|||
|
|
+
|
|||
|
|
+ /* Immediately drop the last ref to the monitor in the hope that this
|
|||
|
|
+ * happens in the middle of the critical section in
|
|||
|
|
+ * g_file_monitor_source_handle_event(), so that any cleanup at the end
|
|||
|
|
+ * of that function is done with a now-finalised file monitor. */
|
|||
|
|
+ g_object_unref (monitor);
|
|||
|
|
+
|
|||
|
|
+ /* Re-create the monitor and do the same again for deleting the file, to
|
|||
|
|
+ * give a second chance at hitting the race condition. */
|
|||
|
|
+ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &local_error);
|
|||
|
|
+ g_assert_no_error (local_error);
|
|||
|
|
+ g_assert_nonnull (monitor);
|
|||
|
|
+
|
|||
|
|
+ /* Delete the file. */
|
|||
|
|
+ g_file_delete (file, NULL, &local_error);
|
|||
|
|
+ g_assert_no_error (local_error);
|
|||
|
|
+
|
|||
|
|
+ /* Drop the ref again. */
|
|||
|
|
+ g_object_unref (monitor);
|
|||
|
|
+ }
|
|||
|
|
+
|
|||
|
|
+ g_object_unref (file);
|
|||
|
|
+}
|
|||
|
|
+
|
|||
|
|
int
|
|||
|
|
main (int argc, char *argv[])
|
|||
|
|
{
|
|||
|
|
@@ -1047,6 +1098,7 @@ main (int argc, char *argv[])
|
|||
|
|
g_test_add ("/monitor/dir-not-existent", Fixture, NULL, setup, test_dir_non_existent, teardown);
|
|||
|
|
g_test_add ("/monitor/cross-dir-moves", Fixture, NULL, setup, test_cross_dir_moves, teardown);
|
|||
|
|
g_test_add ("/monitor/file/hard-links", Fixture, NULL, setup, test_file_hard_links, teardown);
|
|||
|
|
+ g_test_add ("/monitor/finalize-in-callback", Fixture, NULL, setup, test_finalize_in_callback, teardown);
|
|||
|
|
|
|||
|
|
return g_test_run ();
|
|||
|
|
}
|
|||
|
|
--
|
|||
|
|
2.41.0.windows.3
|
|||
|
|
|