static void boxed_finalize(JSContext *context, JSObject *obj) { Boxed *priv; priv = priv_from_js(context, obj); gjs_debug_lifecycle(GJS_DEBUG_GBOXED, "finalize, obj %p priv %p", obj, priv); if (priv == NULL) return; /* wrong class? */ if (priv->gboxed && !priv->not_owning_gboxed) { if (priv->allocated_directly) { g_slice_free1(g_struct_info_get_size (priv->info), priv->gboxed); } else { if (g_type_is_a (priv->gtype, G_TYPE_BOXED)) g_boxed_free (priv->gtype, priv->gboxed); else if (g_type_is_a (priv->gtype, G_TYPE_VARIANT)) g_variant_unref (priv->gboxed); else g_assert_not_reached (); } priv->gboxed = NULL; } if (priv->info) { g_base_info_unref( (GIBaseInfo*) priv->info); priv->info = NULL; } GJS_DEC_COUNTER(boxed); g_slice_free(Boxed, priv); }
static void closure_set_invalid(gpointer data, GClosure *closure) { Closure *self = (Closure*) closure; self->obj = NULL; self->context = NULL; self->runtime = NULL; GJS_DEC_COUNTER(closure); }
static void importer_finalize(JSFreeOp *fop, JSObject *obj) { Importer *priv; priv = JS_GetPrivate(obj); gjs_debug_lifecycle(GJS_DEBUG_IMPORTER, "finalize, obj %p priv %p", obj, priv); if (priv == NULL) return; /* we are the prototype, not a real instance */ GJS_DEC_COUNTER(importer); g_slice_free(Importer, priv); }
static void importer_finalize(JSContext *context, JSObject *obj) { Importer *priv; priv = priv_from_js(context, obj); gjs_debug_lifecycle(GJS_DEBUG_IMPORTER, "finalize, obj %p priv %p", obj, priv); if (priv == NULL) return; /* we are the prototype, not a real instance, so constructor never called */ GJS_DEC_COUNTER(importer); g_slice_free(Importer, priv); }
static void interface_finalize(JSContext *context, JSObject *obj) { Interface *priv; priv = priv_from_js(context, obj); if (priv == NULL) return; if (priv->info != NULL) g_base_info_unref((GIBaseInfo*)priv->info); GJS_DEC_COUNTER(interface); g_slice_free(Interface, priv); }
static void ns_finalize(JSFreeOp *fop, JSObject *obj) { Ns *priv; priv = (Ns *)JS_GetPrivate(obj); gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE, "finalize, obj %p priv %p", obj, priv); if (priv == NULL) return; /* we are the prototype, not a real instance */ if (priv->gi_namespace) g_free(priv->gi_namespace); GJS_DEC_COUNTER(ns); g_slice_free(Ns, priv); }
static void interface_finalize(JSFreeOp *fop, JSObject *obj) { Interface *priv; priv = (Interface*) JS_GetPrivate(obj); if (priv == NULL) return; if (priv->info != NULL) g_base_info_unref((GIBaseInfo*)priv->info); g_clear_pointer(&priv->vtable, (GDestroyNotify)g_type_default_interface_unref); GJS_DEC_COUNTER(interface); g_slice_free(Interface, priv); }
static void param_finalize(JSFreeOp *fop, JSObject *obj) { Param *priv; priv = (Param*) JS_GetPrivate(obj); gjs_debug_lifecycle(GJS_DEBUG_GPARAM, "finalize, obj %p priv %p", obj, priv); if (priv == NULL) return; /* wrong class? */ if (priv->gparam) { g_param_spec_unref(priv->gparam); priv->gparam = NULL; } GJS_DEC_COUNTER(param); g_slice_free(Param, priv); }
static void param_finalize(JSContext *context, JSObject *obj) { Param *priv; priv = priv_from_js(context, obj); gjs_debug_lifecycle(GJS_DEBUG_GPARAM, "finalize, obj %p priv %p", obj, priv); if (priv == NULL) return; /* wrong class? */ if (priv->gparam) { g_param_spec_unref(priv->gparam); priv->gparam = NULL; } GJS_DEC_COUNTER(param); g_slice_free(Param, priv); }
static void error_finalize(JSContext *context, JSObject *obj) { Error *priv; priv = priv_from_js(context, obj); gjs_debug_lifecycle(GJS_DEBUG_GERROR, "finalize, obj %p priv %p", obj, priv); if (priv == NULL) return; /* wrong class? */ g_clear_error (&priv->gerror); if (priv->info) { g_base_info_unref( (GIBaseInfo*) priv->info); priv->info = NULL; } GJS_DEC_COUNTER(gerror); g_slice_free(Error, priv); }
static void fundamental_finalize(JSFreeOp *fop, JSObject *obj) { FundamentalInstance *priv; priv = (FundamentalInstance *) JS_GetPrivate(obj); gjs_debug_lifecycle(GJS_DEBUG_GFUNDAMENTAL, "finalize, obj %p priv %p", obj, priv); if (priv == NULL) return; /* wrong class? */ if (priv->prototype) { if (priv->gfundamental) { _fundamental_remove_object(priv->gfundamental); priv->prototype->unref_function(priv->gfundamental); priv->gfundamental = NULL; } g_slice_free(FundamentalInstance, priv); GJS_DEC_COUNTER(fundamental); } else { Fundamental *proto_priv = (Fundamental *) priv; /* Only unref infos when freeing the prototype */ if (proto_priv->constructor_info) g_base_info_unref (proto_priv->constructor_info); proto_priv->constructor_info = NULL; if (proto_priv->info) g_base_info_unref((GIBaseInfo *) proto_priv->info); proto_priv->info = NULL; g_slice_free(Fundamental, proto_priv); } }
/* Invalidation is like "dispose" - it is guaranteed to happen at * finalize, but may happen before finalize. Normally, g_closure_invalidate() * is called when the "target" of the closure becomes invalid, so that the * source (the signal connection, say can be removed.) The usage above * in invalidate_js_pointers() is typical. Since the target of the closure * is under our control, it's unlikely that g_closure_invalidate() will ever * be called by anyone else, but in case it ever does, it's slightly better * to remove the "keep alive" here rather than in the finalize notifier. * * Unlike "dispose" invalidation only happens once. */ static void closure_invalidated(gpointer data, GClosure *closure) { Closure *c; c = (Closure*) closure; GJS_DEC_COUNTER(closure); gjs_debug_closure("Invalidating closure %p which calls object %p", closure, c->obj); if (c->obj == NULL) { gjs_debug_closure(" (closure %p already dead, nothing to do)", closure); return; } /* this will set c->obj to null if the context is dead */ check_context_valid(c); if (c->obj == NULL) { /* Context is dead here. This happens if, as a side effect of * tearing down the context, the closure was invalidated, * say be some other finalized object that had a ref to * the closure dropping said ref. * * Because c->obj was not NULL at the start of * closure_invalidated, we know that * global_context_finalized() has not been called. So we know * we are not being invalidated from inside * global_context_finalized(). * * That means global_context_finalized() has yet to be called, * but we know it will be called, because the context is dead * and thus its global object should be finalized. * * We can't call gjs_keep_alive_remove_global_child() because * the context is invalid memory and we can't get to the * global object that stores the keep alive. * * So global_context_finalized() could be called on an * already-finalized closure. To avoid this, we temporarily * ref ourselves, and set a flag to remove this ref * in global_context_finalized(). */ gjs_debug_closure(" (closure %p's context was dead, holding ref " "until global object finalize)", closure); c->unref_on_global_object_finalized = TRUE; g_closure_ref(&c->base); } else { /* If the context still exists, then remove our destroy * notifier. Otherwise we would call the destroy notifier on * an already-freed closure. * * This happens in the normal case, when the closure is * invalidated for some reason other than destruction of the * JSContext. */ gjs_debug_closure(" (closure %p's context was alive, " "removing our destroy notifier on global object)", closure); gjs_keep_alive_remove_global_child(c->context, global_context_finalized, c->obj, c); c->obj = NULL; c->context = NULL; c->runtime = NULL; } }
static void closure_finalized(gpointer data, GClosure *closure) { GJS_DEC_COUNTER(closure); }