gobject: drop clearing quark_weak_locations from g_object_real_dispose()

In g_object_unref(), we call _object_unref_clear_weak_locations() before
and after dispose() already. At those places it is necessary to do.

Calling it a third time during g_object_real_dispose() seems not useful,
has unnecessary overhead and actually undesirable.

In particular, because g_object_real_dispose() is the implementation for
the virtual function GObject.dispose(). For subclasses that override dispose(),
it's not well defined at which point they should chain up the parent
implementation (for dispose(), I'd argue that usually they chain up at
the end of their own code). If they chain up at the end, this has no
effect.

This only really matters if you try to register GWeakRef during dipose
and/or resurrect the object.

        static void dispose(GObject *object)
        {
            g_weak_ref_set(&global_weak_ref, object);
            global_ref = g_object_ref(object);
            G_OBJECT_CLASS (parent_class)->dispose (object);
        }

the object was resurrected, but g_object_real_dispose() would clear the
weak ref. That is not desirable, nor does it make sense.

Instead, the virtual function dispose() is called from two places, from
g_object_unref() and g_object_run_dispose(). In both cases, it is
ensured that weak locations are cleared *after* dispatching the virtual
function. Don't do it somewhere in the middle from
g_object_real_dispose().
This commit is contained in:
Thomas Haller 2023-12-21 21:34:36 +01:00
parent fe0347bc64
commit 2952cfd7a7
2 changed files with 5 additions and 6 deletions

View File

@ -1370,11 +1370,6 @@ g_object_real_dispose (GObject *object)
{
g_signal_handlers_destroy (object);
/* GWeakRef and weak_pointer do not call into user code. Clear those first
* so that user code can rely on the state of their weak pointers.
*/
g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL);
/* GWeakNotify and GClosure can call into user code */
g_datalist_id_set_data (&object->qdata, quark_weak_notifies, NULL);
g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
@ -1462,6 +1457,7 @@ g_object_run_dispose (GObject *object)
TRACE (GOBJECT_OBJECT_DISPOSE(object,G_TYPE_FROM_INSTANCE(object), 0));
G_OBJECT_GET_CLASS (object)->dispose (object);
TRACE (GOBJECT_OBJECT_DISPOSE_END(object,G_TYPE_FROM_INSTANCE(object), 0));
g_datalist_id_remove_data (&object->qdata, quark_weak_locations);
g_object_unref (object);
}

View File

@ -615,7 +615,8 @@ weak_reffed_object_dispose (GObject *object)
G_OBJECT_CLASS (weak_reffed_object_parent_class)->dispose (object);
g_assert_null (g_weak_ref_get (weak_reffed->weak_ref));
g_assert_true (object == g_weak_ref_get (weak_reffed->weak_ref));
g_object_unref (object);
}
static void
@ -669,6 +670,8 @@ test_weak_ref_on_run_dispose (void)
g_object_run_dispose (obj);
g_assert_null (g_weak_ref_get (&weak));
g_weak_ref_set (&weak, obj);
g_clear_object (&obj);
g_assert_null (g_weak_ref_get (&weak));
}