| 2771 | } |
| 2772 | |
| 2773 | ObjectInstance::~ObjectInstance() { |
| 2774 | TRACE(GJS_OBJECT_WRAPPER_FINALIZE(this, m_ptr, ns(), name())); |
| 2775 | |
| 2776 | invalidate_closures(); |
| 2777 | |
| 2778 | // Do not keep the queue locked here, as we may want to leave the other |
| 2779 | // threads to queue toggle events till we're owning the GObject so that |
| 2780 | // eventually (once the toggle reference is finally removed) we can be sure |
| 2781 | // that no other toggle event will target this (soon dead) wrapper. |
| 2782 | bool had_toggle_up; |
| 2783 | bool had_toggle_down; |
| 2784 | std::tie(had_toggle_down, had_toggle_up) = |
| 2785 | ToggleQueue::get_default()->cancel(this); |
| 2786 | |
| 2787 | // GObject is not already freed |
| 2788 | if (m_ptr) { |
| 2789 | if (!had_toggle_up && had_toggle_down) { |
| 2790 | g_error( |
| 2791 | "Finalizing wrapper for an object that's scheduled to be " |
| 2792 | "unrooted: %s", |
| 2793 | format_name().c_str()); |
| 2794 | } |
| 2795 | |
| 2796 | if (!m_gobj_disposed) |
| 2797 | g_object_weak_unref(m_ptr, wrapped_gobj_dispose_notify, this); |
| 2798 | |
| 2799 | if (!m_gobj_finalized) |
| 2800 | unset_object_qdata(); |
| 2801 | |
| 2802 | bool was_using_toggle_refs = m_uses_toggle_ref; |
| 2803 | release_native_object(); |
| 2804 | |
| 2805 | if (was_using_toggle_refs) { |
| 2806 | // We need to cancel again, to be sure that no other thread added |
| 2807 | // another toggle reference before we were removing the last one. |
| 2808 | ToggleQueue::get_default()->cancel(this); |
| 2809 | } |
| 2810 | } |
| 2811 | |
| 2812 | if (wrapper_is_rooted()) { |
| 2813 | /* This happens when the refcount on the object is still >1, for example |
| 2814 | * with global objects GDK never frees like GdkDisplay, when we close |
| 2815 | * down the JS runtime. |
| 2816 | */ |
| 2817 | gjs_debug(GJS_DEBUG_GOBJECT, |
| 2818 | "Wrapper was finalized despite being kept alive, has refcount >1"); |
| 2819 | |
| 2820 | debug_lifecycle("Unrooting object"); |
| 2821 | |
| 2822 | discard_wrapper(); |
| 2823 | } |
| 2824 | unlink(); |
| 2825 | |
| 2826 | GJS_DEC_COUNTER(object_instance); |
| 2827 | } |
| 2828 | |
| 2829 | ObjectPrototype::~ObjectPrototype() { |
| 2830 | invalidate_closure_collection(&m_vfuncs, this, &vfunc_invalidated_notify); |