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