/*! \brief Free a gEDA smob. * \par Function Description * Finalizes a gEDA smob for deletion, removing the weak reference. * * Used internally to Guile. */ static size_t smob_free (SCM smob) { void *data; /* If the weak reference has already been cleared, do nothing */ if (!EDASCM_SMOB_VALIDP(smob)) return 0; data = (void *) SCM_SMOB_DATA (smob); /* Otherwise, clear the weak reference */ switch (EDASCM_SMOB_TYPE (smob)) { case GEDA_SMOB_TOPLEVEL: s_toplevel_weak_unref ((TOPLEVEL *) data, smob_weakref_notify, smob); break; case GEDA_SMOB_PAGE: s_page_weak_unref ((PAGE *) data, smob_weakref_notify, smob); break; case GEDA_SMOB_OBJECT: /* See edascm_from_object() for an explanation of why OBJECT * smobs store a TOPLEVEL in the second data word */ s_object_weak_unref ((OBJECT *) data, smob_weakref_notify, smob); s_toplevel_weak_unref ((TOPLEVEL *) SCM_SMOB_DATA_2 (smob), smob_weakref2_notify, smob); break; default: /* This should REALLY definitely never be run */ g_critical ("%s: received bad smob flags.", __FUNCTION__); } /* If the smob is marked as garbage-collectable, destroy its * contents. * * Because PAGEs and TOPLEVELs should never be garbage collected, * emit critical warnings if the GC tries to free them. */ if (EDASCM_SMOB_GCP (smob)) { switch (EDASCM_SMOB_TYPE (smob)) { case GEDA_SMOB_TOPLEVEL: g_critical ("%s: Blocked garbage-collection of TOPLEVEL %p", __FUNCTION__, data); break; case GEDA_SMOB_PAGE: g_critical ("%s: Blocked garbage-collection of PAGE %p", __FUNCTION__, data); break; case GEDA_SMOB_OBJECT: /* See edascm_from_object() for an explanation of why OBJECT * smobs store a TOPLEVEL in the second data word */ s_delete_object ((TOPLEVEL *) SCM_SMOB_DATA_2 (smob), (OBJECT *) data); break; default: /* This should REALLY definitely never be run */ g_critical ("%s: received bad smob flags.", __FUNCTION__); } } return 0; }
/*! \brief Set whether a gEDA object may be garbage collected. * \ingroup guile_c_iface * \par Function Description * If \a gc is non-zero, allow the structure represented by \a smob to * be destroyed when \a smob is garbage-collected. * * \param [in,out] smob Smob for which to set garbage-collection * permission. * \param [in] gc If non-zero, permit garbage collection. */ void edascm_c_set_gc (SCM smob, int gc) { EDASCM_ASSERT_SMOB_VALID (smob); int current = EDASCM_SMOB_GCP (smob); /* Ensure that when smob becomes garbage-collectible, it's removed * from the Scheme value cache, and that when it stops being * garbage-collectible it's cached for re-use. */ if (gc && !current) smob_cache_remove ((void *) SCM_SMOB_DATA (smob)); if (!gc && current) smob_cache_add ((void *) SCM_SMOB_DATA (smob), smob); EDASCM_SMOB_SET_GC (smob, gc); }
/*! \brief Free a gEDA smob. * \par Function Description * Finalizes a gEDA smob for deletion, removing the weak reference. * * Used internally to Guile. */ static size_t smob_free (SCM smob) { void *data; /* If the weak reference has already been cleared, do nothing */ if (!EDASCM_SMOB_VALIDP(smob)) return 0; data = (void *) SCM_SMOB_DATA (smob); /* If the smob is being finalized, it must not be in the cache! */ g_warn_if_fail (!smob_cache_contains (data)); /* Otherwise, clear the weak reference */ switch (EDASCM_SMOB_TYPE (smob)) { case GEDA_SMOB_TOPLEVEL: s_toplevel_weak_unref ((TOPLEVEL *) data, smob_weakref_notify, unpack_as_pointer (smob)); break; case GEDA_SMOB_PAGE: s_page_weak_unref ((PAGE *) data, smob_weakref_notify, unpack_as_pointer (smob)); break; case GEDA_SMOB_OBJECT: /* See edascm_from_object() for an explanation of why OBJECT * smobs store a TOPLEVEL in the second data word */ s_object_weak_unref ((OBJECT *) data, smob_weakref2_notify, unpack_as_pointer (smob)); break; case GEDA_SMOB_CONFIG: g_object_unref (G_OBJECT (data)); break; case GEDA_SMOB_CLOSURE: break; default: /* This should REALLY definitely never be run */ g_critical ("%s: received bad smob flags.", __FUNCTION__); } /* If the smob is marked as garbage-collectable, destroy its * contents. * * Because PAGEs and TOPLEVELs should never be garbage collected, * emit critical warnings if the GC tries to free them. */ if (EDASCM_SMOB_GCP (smob)) { switch (EDASCM_SMOB_TYPE (smob)) { case GEDA_SMOB_TOPLEVEL: g_critical ("%s: Blocked garbage-collection of TOPLEVEL %p", __FUNCTION__, data); break; case GEDA_SMOB_PAGE: g_critical ("%s: Blocked garbage-collection of PAGE %p", __FUNCTION__, data); break; case GEDA_SMOB_OBJECT: /* See edascm_from_object() for an explanation of why OBJECT * smobs store a TOPLEVEL in the second data word */ s_delete_object ((TOPLEVEL *) SCM_SMOB_DATA_2 (smob), (OBJECT *) data); break; case GEDA_SMOB_CONFIG: /* These are reference counted, so the structure will have * already been destroyed above if appropriate. */ break; case GEDA_SMOB_CLOSURE: break; default: /* This should REALLY definitely never be run */ g_critical ("%s: received bad smob flags.", __FUNCTION__); } } return 0; }