[glib-networking] tests: fix flaky teardown weak ref logic



commit edfbaa668cee0ca5f35bb350f0fce8259bac7467
Author: Ole André Vadla Ravnås <oleavr gmail com>
Date:   Mon May 31 18:23:01 2021 +0200

    tests: fix flaky teardown weak ref logic
    
    Should avoid g_object_add_weak_pointer() in multi-threaded scenarios as
    it's not thread-safe.

 tls/tests/connection.c      | 34 +++++++++++++++++++++++-----------
 tls/tests/dtls-connection.c | 34 +++++++++++++++++++++++-----------
 2 files changed, 46 insertions(+), 22 deletions(-)
---
diff --git a/tls/tests/connection.c b/tls/tests/connection.c
index a105ceb..00ac7fd 100644
--- a/tls/tests/connection.c
+++ b/tls/tests/connection.c
@@ -121,6 +121,21 @@ setup_connection (TestConnection *test, gconstpointer data)
       g_assert_true (!(var));                                \
     }
 
+/* Waits about 10 seconds for @var's ref_count to drop to 1 */
+#define WAIT_UNTIL_UNREFFED(var)                                \
+  if (var)                                                      \
+    {                                                           \
+      int i;                                                    \
+                                                                \
+      for (i = 0; i < 13 && G_OBJECT (var)->ref_count > 1; i++) \
+        {                                                       \
+          g_usleep (1000 * (1 << i));                           \
+          g_main_context_iteration (NULL, FALSE);               \
+        }                                                       \
+                                                                \
+      g_assert_cmpuint (G_OBJECT (var)->ref_count, ==, 1);      \
+    }
+
 static void
 wait_until_server_finished (TestConnection *test)
 {
@@ -137,35 +152,32 @@ teardown_connection (TestConnection *test, gconstpointer data)
        * which we want to wait for it to release if we're valgrinding.
        */
       g_socket_listener_close (G_SOCKET_LISTENER (test->service));
-      g_object_add_weak_pointer (G_OBJECT (test->service), (gpointer *)&test->service);
+      WAIT_UNTIL_UNREFFED (test->service);
       g_object_unref (test->service);
-      WAIT_UNTIL_UNSET (test->service);
+      test->service = NULL;
     }
 
   if (test->server_connection)
     {
       WAIT_UNTIL_UNSET (test->server_running);
 
-      g_object_add_weak_pointer (G_OBJECT (test->server_connection),
-                                 (gpointer *)&test->server_connection);
+      WAIT_UNTIL_UNREFFED (test->server_connection);
       g_object_unref (test->server_connection);
-      WAIT_UNTIL_UNSET (test->server_connection);
+      test->server_connection = NULL;
     }
 
   if (test->client_connection)
     {
-      g_object_add_weak_pointer (G_OBJECT (test->client_connection),
-                                 (gpointer *)&test->client_connection);
+      WAIT_UNTIL_UNREFFED (test->client_connection);
       g_object_unref (test->client_connection);
-      WAIT_UNTIL_UNSET (test->client_connection);
+      test->client_connection = NULL;
     }
 
   if (test->database)
     {
-      g_object_add_weak_pointer (G_OBJECT (test->database),
-                                 (gpointer *)&test->database);
+      WAIT_UNTIL_UNREFFED (test->database);
       g_object_unref (test->database);
-      WAIT_UNTIL_UNSET (test->database);
+      test->database = NULL;
     }
 
   g_clear_object (&test->address);
diff --git a/tls/tests/dtls-connection.c b/tls/tests/dtls-connection.c
index 815b005..7244c08 100644
--- a/tls/tests/dtls-connection.c
+++ b/tls/tests/dtls-connection.c
@@ -119,6 +119,21 @@ setup_connection (TestConnection *test, gconstpointer data)
       g_assert_true (!(var));                             \
     }
 
+/* Waits about 10 seconds for @var's ref_count to drop to 1 */
+#define WAIT_UNTIL_UNREFFED(var)                                  \
+  if (var)                                                        \
+    {                                                             \
+      int i;                                                      \
+                                                                  \
+      for (i = 0; i < 13 && G_OBJECT (var)->ref_count > 1; i++)   \
+        {                                                         \
+          g_usleep (1000 * (1 << i));                             \
+          g_main_context_iteration (test->client_context, FALSE); \
+        }                                                         \
+                                                                  \
+      g_assert_cmpuint (G_OBJECT (var)->ref_count, ==, 1);        \
+    }
+
 static void
 teardown_connection (TestConnection *test, gconstpointer data)
 {
@@ -135,10 +150,9 @@ teardown_connection (TestConnection *test, gconstpointer data)
     {
       WAIT_UNTIL_UNSET (test->server_running);
 
-      g_object_add_weak_pointer (G_OBJECT (test->server_connection),
-                                 (gpointer *)&test->server_connection);
+      WAIT_UNTIL_UNREFFED (test->server_connection);
       g_object_unref (test->server_connection);
-      WAIT_UNTIL_UNSET (test->server_connection);
+      test->server_connection = NULL;
     }
 
   if (test->server_socket)
@@ -149,25 +163,23 @@ teardown_connection (TestConnection *test, gconstpointer data)
       /* The outstanding accept_async will hold a ref on test->server_socket,
        * which we want to wait for it to release if we're valgrinding.
        */
-      g_object_add_weak_pointer (G_OBJECT (test->server_socket), (gpointer *)&test->server_socket);
+      WAIT_UNTIL_UNREFFED (test->server_socket);
       g_object_unref (test->server_socket);
-      WAIT_UNTIL_UNSET (test->server_socket);
+      test->server_socket = NULL;
     }
 
   if (test->client_connection)
     {
-      g_object_add_weak_pointer (G_OBJECT (test->client_connection),
-                                 (gpointer *)&test->client_connection);
+      WAIT_UNTIL_UNREFFED (test->client_connection);
       g_object_unref (test->client_connection);
-      WAIT_UNTIL_UNSET (test->client_connection);
+      test->client_connection = NULL;
     }
 
   if (test->database)
     {
-      g_object_add_weak_pointer (G_OBJECT (test->database),
-                                 (gpointer *)&test->database);
+      WAIT_UNTIL_UNREFFED (test->database);
       g_object_unref (test->database);
-      WAIT_UNTIL_UNSET (test->database);
+      test->database = NULL;
     }
 
   g_clear_object (&test->address);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]