This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Guile-C interfacing and defating garbage collection


Richard Frith-Macdonald <richard@brainstorm.co.uk> writes:

> How can I be sure that the procedure has not been garbage collected between
> stage 1 and stage 2?

libguile has some functions to help you with protecting SCM values
from the garbage collector.

    scm_permanent_object(X) will protect X for all time being.

    scm_protect_object(X) will protect X until you call
    scm_unprotect_object(X).

But note that scm_protect_object/scm_unprotect_object do *not* work in
a nested fashion.  Calling scm_unprotect_object will make X completely
unprotected regardless how many times you have called
scm_protect_object on it.

You are maybe better off with using these functions:

    static SCM protects;

    SCM
    protect_nested (SCM obj)
    {
      SCM_SETCAR (protects, scm_cons (obj, SCM_CAR (protects)));
      return obj;
    }

    void
    unprotect_nested (SCM obj)
    {
      SCM walk;
      SCM *prev;

      for (prev = SCM_CARLOC (protects), walk = SCM_CAR (protects);
	   SCM_NIMP (walk) && SCM_CONSP (walk);
	   walk = SCM_CDR (walk))
	{
	  if (SCM_CAR (walk) == obj)
	    {
	      *prev = SCM_CDR (walk);
	      break;
	    }
	  else
	    prev = SCM_CDRLOC (walk);
	}
    }

In your initialization code

    protects = scm_permanent_object (scm_cons (SCM_EOL, SCM_BOOL_F));