[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: gaf.git: branch: master updated (1.7.1-20110619-310-g78c8ee9)



The branch, master has been updated
       via  78c8ee905dad0dbfde548debb2be5790d4b2fb71 (commit)
      from  ec9259f77f9af88f0bf3dbaa1c09a92b87b2c36b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 libgeda/src/scheme_smob.c |   29 ++++++++++++++++++++++++++---
 1 files changed, 26 insertions(+), 3 deletions(-)


=================
 Commit Messages
=================

commit 78c8ee905dad0dbfde548debb2be5790d4b2fb71
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>

    scheme-api: Store a TOPLEVEL pointer in OBJECT smobs.
    
    When an OBJECT smob is created in Scheme code, and then goes out of
    scope without being added to a component or to a page, we need to be
    able to delete the object from the Guile garbage collector.  This
    deletion occurs in a smob free function.
    
    To delete an OBJECT, we need to call s_object_delete(), which requires
    an additional TOPLEVEL argument.  Previously, we have obtained a
    TOPLEVEL by using edascm_c_current_toplevel().  Unfortunately, this
    (indirectly) calls scm_fluid_ref(), which is not permitted to be
    called from a smob free function; if called in that context, it may
    cause a deadlock.
    
    This patch alters OBJECT smobs to be double-length smobs, with the
    current TOPLEVEL at the time the smob was created baked into the
    second data word.  This avoids the need to use
    edascm_c_current_toplevel() when garbarge-collecting an OBJECT, but
    it's also somewhat hacky. :-(
    
    Closes-bug: lp-909358

:100644 100644 f3a90f2... 7fa1305... M	libgeda/src/scheme_smob.c

=========
 Changes
=========

commit 78c8ee905dad0dbfde548debb2be5790d4b2fb71
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>

    scheme-api: Store a TOPLEVEL pointer in OBJECT smobs.
    
    When an OBJECT smob is created in Scheme code, and then goes out of
    scope without being added to a component or to a page, we need to be
    able to delete the object from the Guile garbage collector.  This
    deletion occurs in a smob free function.
    
    To delete an OBJECT, we need to call s_object_delete(), which requires
    an additional TOPLEVEL argument.  Previously, we have obtained a
    TOPLEVEL by using edascm_c_current_toplevel().  Unfortunately, this
    (indirectly) calls scm_fluid_ref(), which is not permitted to be
    called from a smob free function; if called in that context, it may
    cause a deadlock.
    
    This patch alters OBJECT smobs to be double-length smobs, with the
    current TOPLEVEL at the time the smob was created baked into the
    second data word.  This avoids the need to use
    edascm_c_current_toplevel() when garbarge-collecting an OBJECT, but
    it's also somewhat hacky. :-(
    
    Closes-bug: lp-909358

diff --git a/libgeda/src/scheme_smob.c b/libgeda/src/scheme_smob.c
index f3a90f2..7fa1305 100644
--- a/libgeda/src/scheme_smob.c
+++ b/libgeda/src/scheme_smob.c
@@ -72,6 +72,19 @@ smob_weakref_notify (void *target, void *smob) {
   SCM_SET_SMOB_DATA (s, NULL);
 }
 
+/*! \brief Weak reference notify function for double-length gEDA smobs.
+ * \par Function Description
+ * Clears a gEDA smob's second pointer when the target object is
+ * destroyed.
+ *
+ * \see edascm_from_object().
+ */
+static void
+smob_weakref2_notify (void *target, void *smob) {
+  SCM s = (SCM) smob;
+  SCM_SET_SMOB_DATA_2 (s, NULL);
+}
+
 /*! \brief Free a gEDA smob.
  * \par Function Description
  * Finalizes a gEDA smob for deletion, removing the weak reference.
@@ -121,7 +134,9 @@ smob_free (SCM smob)
                  __FUNCTION__, data);
       break;
     case GEDA_SMOB_OBJECT:
-      s_delete_object (edascm_c_current_toplevel(), (OBJECT *) data);
+      /*! 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 */
@@ -271,6 +286,12 @@ edascm_to_page (SCM smob)
  *   edascm_c_set_gc (x, 1);
  * \endcode
  *
+ * \fixme We currently have to bake a TOPLEVEL pointer into the smob,
+ * so that if the object becomes garbage-collectable we can obtain a
+ * TOPLEVEL to use for deleting the smob without accessing the
+ * TOPLEVEL fluid and potentially causing a race condition (see bug
+ * 909358).
+ *
  * \param object #OBJECT to create a smob for.
  * \return a smob representing \a object.
  */
@@ -278,12 +299,14 @@ SCM
 edascm_from_object (OBJECT *object)
 {
   SCM smob;
+  TOPLEVEL *toplevel = edascm_c_current_toplevel ();
 
-  SCM_NEWSMOB (smob, geda_smob_tag, object);
+  SCM_NEWSMOB2 (smob, geda_smob_tag, object, toplevel);
   SCM_SET_SMOB_FLAGS (smob, GEDA_SMOB_OBJECT);
 
-  /* Set weak reference */
+  /* Set weak references */
   s_object_weak_ref (object, smob_weakref_notify, smob);
+  s_toplevel_weak_ref (toplevel, smob_weakref2_notify, smob);
 
   return smob;
 }




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs