| [ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
5.5.6 Remembering During Operations
It’s important that a smob is visible to the garbage collector whenever its contents are being accessed. Otherwise it could be freed while code is still using it.
For example, consider a procedure to convert image data to a list of pixel values.
SCM
image_to_list (SCM image_smob)
{
struct image *image;
SCM lst;
int i;
scm_assert_smob_type (image_tag, image_smob);
image = (struct image *) SCM_SMOB_DATA (image_smob);
lst = SCM_EOL;
for (i = image->width * image->height - 1; i >= 0; i--)
lst = scm_cons (scm_from_char (image->pixels[i]), lst);
scm_remember_upto_here_1 (image_smob);
return lst;
}
In the loop, only the image pointer is used and the C compiler
has no reason to keep the image_smob value anywhere. If
scm_cons results in a garbage collection, image_smob might
not be on the stack or anywhere else and could be freed, leaving the
loop accessing freed data. The use of scm_remember_upto_here_1
prevents this, by creating a reference to image_smob after all
data accesses.
There’s no need to do the same for lst, since that’s the return
value and the compiler will certainly keep it in a register or
somewhere throughout the routine.
The clear_image example previously shown (see section Type checking)
also used scm_remember_upto_here_1 for this reason.
It’s only in quite rare circumstances that a missing
scm_remember_upto_here_1 will bite, but when it happens the
consequences are serious. Fortunately the rule is simple: whenever
calling a Guile library function or doing something that might, ensure
that the SCM of a smob is referenced past all accesses to its
insides. Do this by adding an scm_remember_upto_here_1 if
there are no other references.
In a multi-threaded program, the rule is the same. As far as a given thread is concerned, a garbage collection still only occurs within a Guile library function, not at an arbitrary time. (Guile waits for all threads to reach one of its library functions, and holds them there while the collector runs.)
| [ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on February 3, 2012 using texi2html 5.0.
