[gjs/wip/3v1n0/toggle-queue-tests: 1/15] gjs-test-tools: Ensure we use thread safe access to the saved object




commit cbd14c67727e7b06029da2a1b0c2da7e057c9a1d
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Wed Apr 28 19:21:54 2021 +0200

    gjs-test-tools: Ensure we use thread safe access to the saved object
    
    Since we use this for testing actions from multiple threads, it's better
    to ensure that we have safe access to the variables.
    
    So use an atomic pointer to keep track of the saved object that allows
    us better control and make ThreadSanitizer happier.

 .../js/libgjstesttools/gjs-test-tools.cpp          | 29 ++++++++++++----------
 .../js/libgjstesttools/gjs-test-tools.h            |  3 +++
 2 files changed, 19 insertions(+), 13 deletions(-)
---
diff --git a/installed-tests/js/libgjstesttools/gjs-test-tools.cpp 
b/installed-tests/js/libgjstesttools/gjs-test-tools.cpp
index 276303af..c7d0f583 100644
--- a/installed-tests/js/libgjstesttools/gjs-test-tools.cpp
+++ b/installed-tests/js/libgjstesttools/gjs-test-tools.cpp
@@ -18,7 +18,7 @@
 #    include <glib-unix.h> /* for g_unix_open_pipe */
 #endif
 
-static GObject* m_tmp_object = NULL;
+static std::atomic<GObject*> m_tmp_object = nullptr;
 static GWeakRef m_tmp_weak;
 static std::unordered_set<GObject*> m_finalized_objects;
 static std::mutex m_finalized_objects_lock;
@@ -33,11 +33,7 @@ struct FinalizedObjectsLocked {
 void gjs_test_tools_init() {}
 
 void gjs_test_tools_reset() {
-    if (!FinalizedObjectsLocked()->count(m_tmp_object))
-        g_clear_object(&m_tmp_object);
-    else
-        m_tmp_object = nullptr;
-
+    gjs_test_tools_clear_saved();
     g_weak_ref_set(&m_tmp_weak, nullptr);
 
     FinalizedObjectsLocked()->clear();
@@ -85,15 +81,22 @@ void gjs_test_tools_delayed_dispose(GObject* object, int interval) {
 }
 
 void gjs_test_tools_save_object(GObject* object) {
-    g_assert(!m_tmp_object);
-    g_set_object(&m_tmp_object, object);
-    monitor_object_finalization(object);
+    g_object_ref(object);
+    gjs_test_tools_save_object_unreffed(object);
 }
 
 void gjs_test_tools_save_object_unreffed(GObject* object) {
-    g_assert(!m_tmp_object);
-    m_tmp_object = object;
-    monitor_object_finalization(object);
+    GObject* expected = nullptr;
+    g_assert(m_tmp_object.compare_exchange_strong(expected, object));
+}
+
+void gjs_test_tools_clear_saved() {
+    if (!FinalizedObjectsLocked()->count(m_tmp_object)) {
+        auto* object = m_tmp_object.exchange(nullptr);
+        g_clear_object(&object);
+    } else {
+        m_tmp_object = nullptr;
+    }
 }
 
 void gjs_test_tools_ref_other_thread(GObject* object) {
@@ -199,7 +202,7 @@ GObject* gjs_test_tools_get_saved() {
     if (FinalizedObjectsLocked()->count(m_tmp_object))
         m_tmp_object = nullptr;
 
-    return static_cast<GObject*>(g_steal_pointer(&m_tmp_object));
+    return m_tmp_object.exchange(nullptr);
 }
 
 /**
diff --git a/installed-tests/js/libgjstesttools/gjs-test-tools.h 
b/installed-tests/js/libgjstesttools/gjs-test-tools.h
index 0417adc4..0e1595bc 100644
--- a/installed-tests/js/libgjstesttools/gjs-test-tools.h
+++ b/installed-tests/js/libgjstesttools/gjs-test-tools.h
@@ -65,6 +65,9 @@ GObject* gjs_test_tools_steal_saved();
 _GJS_TEST_TOOL_EXTERN
 GObject* gjs_test_tools_peek_saved();
 
+_GJS_TEST_TOOL_EXTERN
+void gjs_test_tools_clear_saved();
+
 _GJS_TEST_TOOL_EXTERN
 void gjs_test_tools_save_weak(GObject* object);
 


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