[gjs/gnome-3-28] object: Set up a single weak ref on the context
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/gnome-3-28] object: Set up a single weak ref on the context
- Date: Sat, 1 Dec 2018 20:59:28 +0000 (UTC)
commit e5742d55f7e7ead246637a1c259d444ba031f081
Author: Carlos Garnacho <carlosg gnome org>
Date: Sun Apr 15 17:59:58 2018 +0200
object: Set up a single weak ref on the context
Instead of setting up a callback when rooting GjsMaybeOwned objects,
set up a single weak ref on the GjsContext to reset all currently
rooted objects by iterating the ObjectInstance list.
https://gitlab.gnome.org/GNOME/gjs/issues/144
Closes: #144
(cherry picked from commit 0f5c81e07c79f74d1b1a6a2365defaeb1452b11d)
gi/object.cpp | 42 +++++++++++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 13 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 913823d0..f25e2685 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -144,6 +144,7 @@ using ParamRef = std::unique_ptr<GParamSpec, decltype(&g_param_spec_unref)>;
using ParamRefArray = std::vector<ParamRef>;
static std::unordered_map<GType, ParamRefArray> class_init_properties;
+static bool context_weak_pointer_callback = false;
static bool weak_pointer_callback = false;
ObjectInstance *wrapped_gobject_list;
@@ -1043,20 +1044,24 @@ wrapped_gobj_dispose_notify(gpointer data,
}
static void
-gobj_no_longer_kept_alive_func(JS::HandleObject obj,
- void *data)
+context_dispose_notify(gpointer data,
+ GObject *where_the_object_was)
{
- ObjectInstance *priv;
-
- priv = (ObjectInstance *) data;
+ ObjectInstance *priv = wrapped_gobject_list;
+ while (priv) {
+ ObjectInstance *next = priv->instance_link.next();
- gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "GObject wrapper %p for GObject "
- "%p (%s) was rooted but is now unrooted due to "
- "GjsContext dispose", obj.get(), priv->gobj,
- G_OBJECT_TYPE_NAME(priv->gobj));
+ if (priv->keep_alive.rooted()) {
+ gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "GObject wrapper %p for GObject "
+ "%p (%s) was rooted but is now unrooted due to "
+ "GjsContext dispose", obj.get(), priv->gobj,
+ G_OBJECT_TYPE_NAME(priv->gobj));
+ priv->keep_alive.reset();
+ object_instance_unlink(priv);
+ }
- priv->keep_alive.reset();
- object_instance_unlink(priv);
+ priv = next;
+ }
}
static void
@@ -1124,7 +1129,7 @@ handle_toggle_up(GObject *gobj)
GjsContext *context = gjs_context_get_current();
gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Rooting object");
auto cx = static_cast<JSContext *>(gjs_context_get_native_context(context));
- priv->keep_alive.switch_to_rooted(cx, gobj_no_longer_kept_alive_func, priv);
+ priv->keep_alive.switch_to_rooted(cx);
}
}
@@ -1362,6 +1367,16 @@ ensure_weak_pointer_callback(JSContext *cx)
}
}
+static void
+ensure_context_weak_pointer_callback(JSContext *cx)
+{
+ if (!context_weak_pointer_callback) {
+ auto gjs_cx = static_cast<GjsContext *>(JS_GetContextPrivate(cx));
+ g_object_weak_ref(G_OBJECT(gjs_cx), context_dispose_notify, NULL);
+ context_weak_pointer_callback = true;
+ }
+}
+
static void
associate_js_gobject (JSContext *context,
JS::HandleObject object,
@@ -1379,6 +1394,7 @@ associate_js_gobject (JSContext *context,
priv->keep_alive = object;
ensure_weak_pointer_callback(context);
+ ensure_context_weak_pointer_callback(context);
object_instance_link(priv);
g_object_weak_ref(gobj, wrapped_gobj_dispose_notify, priv);
@@ -1405,7 +1421,7 @@ ensure_uses_toggle_ref(JSContext *cx,
* wrappee).
*/
priv->uses_toggle_ref = true;
- priv->keep_alive.switch_to_rooted(cx, gobj_no_longer_kept_alive_func, priv);
+ priv->keep_alive.switch_to_rooted(cx);
g_object_add_toggle_ref(priv->gobj, wrapped_gobj_toggle_notify, nullptr);
/* We now have both a ref and a toggle ref, we only want the toggle ref.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]