/*! \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 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; }