[gjs/gnome-40: 5/30] object: Switch back to normal references on disposal
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/gnome-40: 5/30] object: Switch back to normal references on disposal
- Date: Wed, 5 May 2021 20:41:25 +0000 (UTC)
commit a34823b9250877322c4d927515d155b3d5f081b5
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Thu Mar 25 20:03:41 2021 +0100
object: Switch back to normal references on disposal
When an object is disposed we already remove the toggle reference on it
and we avoid that nothing will unref it again, however this can lead to
troubles when something else owns the last reference at garbage
collecting point if we didn't release the object earlier because in
~ObjectInstance we still expect to have a reference.
To avoid this, let's just keep it simpler and switch back to normal
reference again at dispose notify.
The ordering here is important though, as referencing the object may
cause a toggle-up event to happen, but we need to do it before removing
the toggle reference (as that could be the only one we have), however
after that we're still forcing a toggle-down event to happen, so we'll
still be unrooted afterwards.
Fixes: #399
(cherry-picked from commit 627ea90f)
gi/object.cpp | 6 +++---
installed-tests/js/testGtk3.js | 20 ++++++++++++++------
2 files changed, 17 insertions(+), 9 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 75b29be3..f42fb0c8 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -1090,8 +1090,10 @@ ObjectInstance::gobj_dispose_notify(void)
m_gobj_disposed = true;
if (m_uses_toggle_ref) {
+ g_object_ref(m_ptr.get());
g_object_remove_toggle_ref(m_ptr, wrapped_gobj_toggle_notify, this);
wrapped_gobj_toggle_notify(this, m_ptr, TRUE);
+ m_uses_toggle_ref = false;
}
}
@@ -1305,9 +1307,7 @@ void
ObjectInstance::release_native_object(void)
{
discard_wrapper();
- if (m_uses_toggle_ref && m_gobj_disposed)
- m_ptr.release();
- else if (m_uses_toggle_ref)
+ if (m_uses_toggle_ref && !m_gobj_disposed)
g_object_remove_toggle_ref(m_ptr.release(), wrapped_gobj_toggle_notify,
this);
else
diff --git a/installed-tests/js/testGtk3.js b/installed-tests/js/testGtk3.js
index fd0608d1..8d08481f 100644
--- a/installed-tests/js/testGtk3.js
+++ b/installed-tests/js/testGtk3.js
@@ -191,19 +191,27 @@ describe('Gtk overrides', function () {
'Gtk overrides avoid crashing and print a stack trace');
});
- it('GTK vfuncs can be explicitly called during disposition', function () {
- let called;
- const GoodLabel = GObject.registerClass(class GoodLabel extends Gtk.Label {
+ it('GTK vfuncs are not called if the object is disposed', function () {
+ const spy = jasmine.createSpy('vfunc_destroy');
+ const NotSoGoodLabel = GObject.registerClass(class NotSoGoodLabel extends Gtk.Label {
vfunc_destroy() {
- called = true;
+ spy();
}
});
- let label = new GoodLabel();
+ let label = new NotSoGoodLabel();
+
label.destroy();
- expect(called).toBeTruthy();
+ expect(spy).toHaveBeenCalledTimes(1);
+
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
+ '*during garbage collection*');
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
+ '*destroy*');
label = null;
System.gc();
+ GLib.test_assert_expected_messages_internal('Gjs', 'testGtk3.js', 0,
+ 'GTK vfuncs are not called if the object is disposed');
});
it('accepts string in place of GdkAtom', function () {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]