[gjs: 3/10] boxed: Mark pointer as unowned when discarding boxed object



commit 7b330751fbd260764c852519e9d22e55915e2526
Author: Philip Chimento <philip chimento gmail com>
Date:   Sun Feb 24 11:11:39 2019 -0800

    boxed: Mark pointer as unowned when discarding boxed object
    
    Sometimes, in the constructor of a boxed object, we will delegate to
    another constructor, such as GLib.Error() or GLib.Variant.new_internal()
    and replace the object under construction by the object returned by
    the delegated constructor.
    
    When that happens, the internal GBoxed pointer of the BoxedInstance
    remains null. That causes problems when eventually the discarded boxed
    object is garbage collected, and we try to free the pointer. In those
    cases, mark it as unowned so it is not freed.

 gi/boxed.cpp | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 8b1118ea..7c40d83e 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -304,7 +304,13 @@ bool BoxedInstance::constructor_impl(JSContext* context, JS::HandleObject obj,
         if (!boxed_invoke_constructor(context, obj, atoms.new_internal(), args))
             return false;
 
-        debug_lifecycle("Boxed construction delegated to GVariant constructor");
+        // The return value of GLib.Variant.new_internal() gets its own
+        // BoxedInstance, and the one we're setting up in this constructor is
+        // discarded.
+        m_not_owning_ptr = true;
+        debug_lifecycle(
+            "Boxed construction delegated to GVariant constructor, "
+            "boxed object discarded");
 
         return true;
     }
@@ -354,7 +360,13 @@ bool BoxedInstance::constructor_impl(JSContext* context, JS::HandleObject obj,
                 return false;
         }
 
-        debug_lifecycle("Boxed construction delegated to JS constructor");
+        // The return value of the JS constructor gets its own BoxedInstance,
+        // and this one is discarded. Mark that the boxed pointer doesn't need
+        // to be freed, since it remains null.
+        m_not_owning_ptr = true;
+        debug_lifecycle(
+            "Boxed construction delegated to JS constructor, "
+            "boxed object discarded");
 
         return true;
     } else {


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