Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
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);
}
Пример #8
0
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);
}
Пример #9
0
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);
}
Пример #10
0
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);
}
Пример #11
0
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);
    }
}
Пример #12
0
/* 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;
    }
}
Пример #13
0
static void
closure_finalized(gpointer data,
                  GClosure *closure)
{
    GJS_DEC_COUNTER(closure);
}