Add interface to disable automatic finalization
[bpt/guile.git] / doc / ref / libguile-smobs.texi
index b424017..f12ab13 100644 (file)
@@ -1,6 +1,6 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Guile Reference Manual.
-@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004
+@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011, 2013, 2014
 @c   Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
@@ -28,10 +28,9 @@ datatypes described here.)
 
 @menu
 * Describing a New Type::       
-* Creating Instances::          
+* Creating Smob Instances::          
 * Type checking::                
 * Garbage Collecting Smobs::    
-* Garbage Collecting Simple Smobs::  
 * Remembering During Operations::  
 * Double Smobs::
 * The Complete Example::          
@@ -40,33 +39,15 @@ datatypes described here.)
 @node Describing a New Type
 @subsection Describing a New Type
 
-To define a new type, the programmer must write four functions to
+To define a new type, the programmer must write two functions to
 manage instances of the type:
 
 @table @code
-@item mark
-Guile will apply this function to each instance of the new type it
-encounters during garbage collection.  This function is responsible for
-telling the collector about any other @code{SCM} values that the object
-has stored.  The default smob mark function does nothing.
-@xref{Garbage Collecting Smobs}, for more details.
-
-@item free
-Guile will apply this function to each instance of the new type that is
-to be deallocated.  The function should release all resources held by
-the object.  This is analogous to the Java finalization method-- it is
-invoked at an unspecified time (when garbage collection occurs) after
-the object is dead.  The default free function frees the smob data (if
-the size of the struct passed to @code{scm_make_smob_type} is non-zero)
-using @code{scm_gc_free}.  @xref{Garbage Collecting Smobs}, for more
-details.
-
 @item print
 Guile will apply this function to each instance of the new type to print
 the value, as for @code{display} or @code{write}.  The default print
 function prints @code{#<NAME ADDRESS>} where @code{NAME} is the first
-argument passed to @code{scm_make_smob_type}.  For more information on
-printing, see @ref{Port Data}.
+argument passed to @code{scm_make_smob_type}.
 
 @item equalp
 If Scheme code asks the @code{equal?} function to compare two instances
@@ -78,11 +59,37 @@ never @code{equal?} unless they are @code{eq?}.
 
 @end table
 
+When the only resource associated with a smob is memory managed by the
+garbage collector---i.e., memory allocated with the @code{scm_gc_malloc}
+functions---this is sufficient.  However, when a smob is associated with
+other kinds of resources, it may be necessary to define one of the
+following functions, or both:
+
+@table @code
+@item mark
+Guile will apply this function to each instance of the new type it
+encounters during garbage collection.  This function is responsible for
+telling the collector about any other @code{SCM} values that the object
+has stored, and that are in memory regions not already scanned by the
+garbage collector.  @xref{Garbage Collecting Smobs}, for more details.
+
+@item free
+Guile will apply this function to each instance of the new type that is
+to be deallocated.  The function should release all resources held by
+the object.  This is analogous to the Java finalization method---it is
+invoked at an unspecified time (when garbage collection occurs) after
+the object is dead.  @xref{Garbage Collecting Smobs}, for more details.
+
+This function operates while the heap is in an inconsistent state and
+must therefore be careful.  @xref{Smobs}, for details about what this
+function is allowed to do.
+@end table
+
 To actually register the new smob type, call @code{scm_make_smob_type}.
 It returns a value of type @code{scm_t_bits} which identifies the new
 smob type.
 
-The four special functions descrtibed above are registered by calling
+The four special functions described above are registered by calling
 one of @code{scm_set_smob_mark}, @code{scm_set_smob_free},
 @code{scm_set_smob_print}, or @code{scm_set_smob_equalp}, as
 appropriate.  Each function is intended to be used at most once per
@@ -92,9 +99,9 @@ type, and the call should be placed immediately following the call to
 There can only be at most 256 different smob types in the system.
 Instead of registering a huge number of smob types (for example, one
 for each relevant C struct in your application), it is sometimes
-better to register just one and implement a second alyer of type
+better to register just one and implement a second layer of type
 dispatching on top of it.  This second layer might use the 16 extra
-bits for as an extended type, for example.
+bits to extend its type, for example.
 
 Here is how one might declare and register a new type representing
 eight-bit gray-scale images:
@@ -128,57 +135,44 @@ init_image_type (void)
 @end example
 
 
-@node Creating Instances
-@subsection Creating Instances
+@node Creating Smob Instances
+@subsection Creating Smob Instances
 
-Normally, smobs can have one @emph{immediate} words of data.  This word
+Normally, smobs can have one @emph{immediate} word of data.  This word
 stores either a pointer to an additional memory block that holds the
 real data, or it might hold the data itself when it fits.  The word is
-of type @code{scm_t_bits} and is large enough for a @code{SCM} value or
-a pointer to @code{void}.
+large enough for a @code{SCM} value, a pointer to @code{void}, or an
+integer that fits into a @code{size_t} or @code{ssize_t}.
 
 You can also create smobs that have two or three immediate words, and
 when these words suffice to store all data, it is more efficient to use
 these super-sized smobs instead of using a normal smob plus a memory
 block.  @xref{Double Smobs}, for their discussion.
 
+Guile provides functions for managing memory which are often helpful
+when implementing smobs.  @xref{Memory Blocks}.
+
 To retrieve the immediate word of a smob, you use the macro
 @code{SCM_SMOB_DATA}.  It can be set with @code{SCM_SET_SMOB_DATA}.
 The 16 extra bits can be accessed with @code{SCM_SMOB_FLAGS} and
 @code{SCM_SET_SMOB_FLAGS}.
 
-Guile provides functions for managing memory which are often helpful
-when implementing smobs.  @xref{Memory Blocks}.
+The two macros @code{SCM_SMOB_DATA} and @code{SCM_SET_SMOB_DATA} treat
+the immediate word as if it were of type @code{scm_t_bits}, which is
+an unsigned integer type large enough to hold a pointer to
+@code{void}.  Thus you can use these macros to store arbitrary
+pointers in the smob word.
+
+When you want to store a @code{SCM} value directly in the immediate
+word of a smob, you should use the macros @code{SCM_SMOB_OBJECT} and
+@code{SCM_SET_SMOB_OBJECT} to access it.
 
 Creating a smob instance can be tricky when it consists of multiple
-steps that allocate resources and might fail.  It is recommended that
-you go about creating a smob in the following way:
-
-@itemize
-@item
-Allocate the memory block for holding the data with
-@code{scm_gc_malloc}.
-@item
-Initialize it to a valid state without calling any functions that might
-cause a non-local exits.  For example, initialize pointers to NULL.
-Also, do not store @code{SCM} values in it that must be protected.
-Initialize these fields with @code{SCM_BOOL_F}.
-
-A valid state is one that can be safely acted upon by the @emph{mark}
-and @emph{free} functions of your smob type.
-@item
-Create the smob using @code{SCM_NEWSMOB}, passing it the initialized
-memory block.  (This step will always succeed.)
-@item
-Complete the initialization of the memory block by, for example,
-allocating additional resources and making it point to them.
-@end itemize
-
-This precedure ensures that the smob is in a valid state as soon as it
-exists, that all resources that are allocated for the smob are properly
-associated with it so that they can be properly freed, and that no
-@code{SCM} values that need to be protected are stored in it while the
-smob does not yet competely exist and thus can not protect them.
+steps that allocate resources.  Most of the time, this is mainly about
+allocating memory to hold associated data structures.  Using memory
+managed by the garbage collector simplifies things: the garbage
+collector will automatically scan those data structures for pointers,
+and reclaim them when they are no longer referenced.
 
 Continuing the example from above, if the global variable
 @code{image_tag} contains a tag returned by @code{scm_make_smob_type},
@@ -196,7 +190,8 @@ make_image (SCM name, SCM s_width, SCM s_height)
 
   /* Step 1: Allocate the memory block.
    */
-  image = (struct image *) scm_gc_malloc (sizeof (struct image), "image");
+  image = (struct image *)
+     scm_gc_malloc (sizeof (struct image), "image");
 
   /* Step 2: Initialize it with straight code.
    */
@@ -208,54 +203,32 @@ make_image (SCM name, SCM s_width, SCM s_height)
 
   /* Step 3: Create the smob.
    */
-  SCM_NEWSMOB (smob, image);
+  smob = scm_new_smob (image_tag, image);
 
   /* Step 4: Finish the initialization.
    */
   image->name = name;
-  image->pixels = scm_gc_malloc (width * height, "image pixels");
+  image->pixels =
+    scm_gc_malloc_pointerless (width * height, "image pixels");
 
   return smob;
 @}
 @end example
 
-Let us look at what might happen when @code{make_image} is called.
-
-The conversions of @var{s_width} and @var{s_height} to @code{int}s might
-fail and signal an error, thus causing a non-local exit.  This is not a
-problem since no resources have been allocated yet that would have to be
-freed.
-
-The allocation of @var{image} in step 1 might fail, but this is likewise
-no problem.
-
-Step 2 can not exit non-locally.  At the end of it, the @var{image}
-struct is in a valid state for the @code{mark_image} and
-@code{free_image} functions (see below).
-
-Step 3 can not exit non-locally either.  This is guaranteed by Guile.
-After it, @var{smob} contains a valid smob that is properly initialized
-and protected, and in turn can properly protect the Scheme values in its
-@var{image} struct.
-
-But before the smob is completely created, @code{SCM_NEWSMOB} might
-cause the garbage collector to run.  During this garbage collection, the
-@code{SCM} values in the @var{image} struct would be invisible to Guile.
-It only gets to know about them via the @code{mark_image} function, but
-that function can not yet do its job since the smob has not been created
-yet.  Thus, it is important to not store @code{SCM} values in the
-@var{image} struct until after the smob has been created.
+We use @code{scm_gc_malloc_pointerless} for the pixel buffer to tell the
+garbage collector not to scan it for pointers.  Calls to
+@code{scm_gc_malloc}, @code{scm_new_smob}, and
+@code{scm_gc_malloc_pointerless} raise an exception in out-of-memory
+conditions; the garbage collector is able to reclaim previously
+allocated memory if that happens.
 
-Step 4, finally, might fail and cause a non-local exit.  In that case,
-the creation of the smob has not been successful.  It will eventually be
-freed by the garbage collector, and all the resources that have been
-allocated for it will be correctly freed by @code{free_image}.
 
 @node Type checking
 @subsection Type checking
 
-Functions that operate on smobs should check that the passed @code{SCM}
-value indeed is a suitable smob before accessing its data.
+Functions that operate on smobs should check that the passed
+@code{SCM} value indeed is a suitable smob before accessing its data.
+They can do this with @code{scm_assert_smob_type}.
 
 For example, here is a simple function that operates on an image smob,
 and checks the type of its argument.
@@ -267,8 +240,7 @@ clear_image (SCM image_smob)
   int area;
   struct image *image;
 
-  SCM_ASSERT (SCM_SMOB_PREDICATE (image_tag, image_smob),
-              image_smob, SCM_ARG1, "clear-image");
+  scm_assert_smob_type (image_tag, image_smob);
 
   image = (struct image *) SCM_SMOB_DATA (image_smob);
   area = image->width * image->height;
@@ -293,8 +265,17 @@ to @code{scm_remember_upto_here_1}.
 @subsection Garbage Collecting Smobs
 
 Once a smob has been released to the tender mercies of the Scheme
-system, it must be prepared to survive garbage collection.  Guile calls
-the @emph{mark} and @emph{free} functions of the smob to manage this.
+system, it must be prepared to survive garbage collection.  In the
+example above, all the memory associated with the smob is managed by the
+garbage collector because we used the @code{scm_gc_} allocation
+functions.  Thus, no special care must be taken: the garbage collector
+automatically scans them and reclaims any unused memory.
+
+However, when data associated with a smob is managed in some other
+way---e.g., @code{malloc}'d memory or file descriptors---it is possible
+to specify a @emph{free} function to release those resources when the
+smob is reclaimed, and a @emph{mark} function to mark Scheme objects
+otherwise invisible to the garbage collector.
 
 As described in more detail elsewhere (@pxref{Conservative GC}), every
 object in the Scheme system has a @dfn{mark bit}, which the garbage
@@ -326,7 +307,9 @@ values will have become dangling references.
 To mark an arbitrary Scheme object, the @emph{mark} function calls
 @code{scm_gc_mark}.
 
-Thus, here is how we might write @code{mark_image}:
+Thus, here is how we might write @code{mark_image}---again this is not
+needed in our example since we used the @code{scm_gc_} allocation
+routines, so this is just for the sake of illustration:
 
 @example
 @group
@@ -381,14 +364,17 @@ type of the @emph{free} function should be @code{size_t}, an unsigned
 integral type; the @emph{free} function should always return zero.
 
 Here is how we might write the @code{free_image} function for the image
-smob type:
+smob type---again for the sake of illustration, since our example does
+not need it thanks to the use of the @code{scm_gc_} allocation routines:
 @example
 size_t
 free_image (SCM image_smob)
 @{
   struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
 
-  scm_gc_free (image->pixels, image->width * image->height, "image pixels");
+  scm_gc_free (image->pixels,
+               image->width * image->height,
+               "image pixels");
   scm_gc_free (image, sizeof (struct image), "image");
 
   return 0;
@@ -399,6 +385,27 @@ During the sweep phase, the garbage collector will clear the mark bits
 on all live objects.  The code which implements a smob need not do this
 itself.
 
+@cindex finalizer
+@cindex finalization
+
+Note that the free function can be called in any context.  In
+particular, if your Guile is built with support for threads, the
+finalizer may be called from any thread that is running Guile.  In Guile
+2.0, finalizers are invoked via ``asyncs'', which interleaves them with
+running Scheme code; @pxref{System asyncs}.  In Guile 2.2 there will be
+a dedicated finalization thread, to ensure that the finalization doesn't
+run within the critical section of any other thread known to Guile.
+
+In either case, finalizers (free functions) run concurrently with the
+main program, and so they need to be async-safe and thread-safe.  If for
+some reason this is impossible, perhaps because you are embedding Guile
+in some application that is not itself thread-safe, you have a few
+options.  One is to use guardians instead of free functions, and arrange
+to pump the guardians for finalizable objects.  @xref{Guardians}, for
+more information.  The other option is to disable automatic finalization
+entirely, and arrange to call @code{scm_run_finalizers ()} at
+appropriate points.  @xref{Smobs}, for more on these interfaces.
+
 There is no way for smob code to be notified when collection is
 complete.
 
@@ -407,33 +414,11 @@ during garbage collection; keep the @emph{mark} and @emph{free}
 functions very simple.  Since collections occur at unpredictable times,
 it is easy for any unusual activity to interfere with normal code.
 
-
-@node Garbage Collecting Simple Smobs
-@subsection Garbage Collecting Simple Smobs
-
-It is often useful to define very simple smob types --- smobs which have
-no data to mark, other than the cell itself, or smobs whose immediate
-data word is simply an ordinary Scheme object, to be marked recursively.
-Guile provides some functions to handle these common cases; you can use
-this function as your smob type's @emph{mark} function, if your smob's
-structure is simple enough.
-
-If the smob refers to no other Scheme objects, then no action is
-necessary; the garbage collector has already marked the smob cell
-itself.  In that case, you can use zero as your mark function.
-
-@deftypefun SCM scm_markcdr (SCM @var{x})
-Mark the references in the smob @var{x}, assuming that @var{x}'s first
-data word contains an ordinary Scheme object, and @var{x} refers to no
-other objects.  This function simply returns @var{x}'s first data word.
-
-This is only useful for simple smobs created by @code{SCM_NEWSMOB} or
-@code{SCM_RETURN_NEWSMOB}, not for smobs allocated as double cells.
-@end deftypefun
-
 @node Remembering During Operations
 @subsection Remembering During Operations
-@cindex Remembering
+@cindex remembering
+
+@c FIXME: Remove this section?
 
 It's important that a smob is visible to the garbage collector
 whenever its contents are being accessed.  Otherwise it could be freed
@@ -449,8 +434,8 @@ image_to_list (SCM image_smob)
   struct image *image;
   SCM lst;
   int i;
-  SCM_ASSERT (SCM_SMOB_PREDICATE (image_tag, image_smob),
-              image_smob, SCM_ARG1, "image->list");
+
+  scm_assert_smob_type (image_tag, image_smob);
 
   image = (struct image *) SCM_SMOB_DATA (image_smob);
   lst = SCM_EOL;
@@ -481,7 +466,7 @@ It's only in quite rare circumstances that a missing
 @code{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
-the @code{SCM} of a smob is referenced past all accesses to its
+that the @code{SCM} of a smob is referenced past all accesses to its
 insides.  Do this by adding an @code{scm_remember_upto_here_1} if
 there are no other references.
 
@@ -494,25 +479,31 @@ while the collector runs.)
 @node Double Smobs
 @subsection Double Smobs
 
+@c FIXME: Remove this section?
+
 Smobs are called smob because they are small: they normally have only
-room for one @code{scm_t_bits} value plus 16 bits.  The reason for
-this is that smobs are directly implemented by using the low-level,
-two-word cells of Guile that are also used to implement pairs, for
-example.  (@pxref{Data Representation} for the details.)  One word of
-the two-word cells is used for @code{SCM_SMOB_DATA}, the other
-contains the 16-bit type tag and the 16 extra bits.
+room for one @code{void*} or @code{SCM} value plus 16 bits.  The
+reason for this is that smobs are directly implemented by using the
+low-level, two-word cells of Guile that are also used to implement
+pairs, for example.  (@pxref{Data Representation} for the
+details.)  One word of the two-word cells is used for
+@code{SCM_SMOB_DATA} (or @code{SCM_SMOB_OBJECT}), the other contains
+the 16-bit type tag and the 16 extra bits.
 
 In addition to the fundamental two-word cells, Guile also has
 four-word cells, which are appropriately called @dfn{double cells}.
 You can use them for @dfn{double smobs} and get two more immediate
 words of type @code{scm_t_bits}.
 
-A double smob is created with @code{SCM_NEWSMOB2} or
-@code{SCM_NEWSMOB3} instead of @code{SCM_NEWSMOB}.  Its immediate
-words can be retrieved with @code{SCM_SMOB_DATA2} and
-@code{SCM_SMOB_DATA3} in addition to @code{SCM_SMOB_DATA}.
-Unsurprisingly, the words can be set with @code{SCM_SET_SMOB_DATA2}
-and @code{SCM_SET_SMOB_DATA3}.
+A double smob is created with @code{scm_new_double_smob}.  Its immediate
+words can be retrieved as @code{scm_t_bits} with @code{SCM_SMOB_DATA_2}
+and @code{SCM_SMOB_DATA_3} in addition to @code{SCM_SMOB_DATA}.
+Unsurprisingly, the words can be set to @code{scm_t_bits} values with
+@code{SCM_SET_SMOB_DATA_2} and @code{SCM_SET_SMOB_DATA_3}.
+
+Of course there are also @code{SCM_SMOB_OBJECT_2},
+@code{SCM_SMOB_OBJECT_3}, @code{SCM_SET_SMOB_OBJECT_2}, and
+@code{SCM_SET_SMOB_OBJECT_3}.
 
 @node The Complete Example
 @subsection The Complete Example
@@ -558,7 +549,8 @@ make_image (SCM name, SCM s_width, SCM s_height)
 
   /* Step 1: Allocate the memory block.
    */
-  image = (struct image *) scm_gc_malloc (sizeof (struct image), "image");
+  image = (struct image *)
+     scm_gc_malloc (sizeof (struct image), "image");
 
   /* Step 2: Initialize it with straight code.
    */
@@ -570,12 +562,13 @@ make_image (SCM name, SCM s_width, SCM s_height)
 
   /* Step 3: Create the smob.
    */
-  SCM_NEWSMOB (smob, image);
+  smob = scm_new_smob (image_tag, image);
 
   /* Step 4: Finish the initialization.
    */
   image->name = name;
-  image->pixels = scm_gc_malloc (width * height, "image pixels");
+  image->pixels =
+     scm_gc_malloc (width * height, "image pixels");
 
   return smob;
 @}
@@ -586,8 +579,7 @@ clear_image (SCM image_smob)
   int area;
   struct image *image;
 
-  SCM_ASSERT (SCM_SMOB_PREDICATE (image_tag, image_smob),
-              image_smob, SCM_ARG1, "clear-image");
+  scm_assert_smob_type (image_tag, image_smob);
 
   image = (struct image *) SCM_SMOB_DATA (image_smob);
   area = image->width * image->height;
@@ -618,7 +610,9 @@ free_image (SCM image_smob)
 @{
   struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
 
-  scm_gc_free (image->pixels, image->width * image->height, "image pixels");
+  scm_gc_free (image->pixels,
+               image->width * image->height,
+               "image pixels");
   scm_gc_free (image, sizeof (struct image), "image");
 
   return 0;
@@ -655,9 +649,9 @@ Here is a sample build and interaction with the code from the
 
 @example
 zwingli:example-smob$ make CC=gcc
-gcc `guile-config compile`   -c image-type.c -o image-type.o
-gcc `guile-config compile`   -c myguile.c -o myguile.o
-gcc image-type.o myguile.o `guile-config link` -o myguile
+gcc `pkg-config --cflags guile-@value{EFFECTIVE-VERSION}` -c image-type.c -o image-type.o
+gcc `pkg-config --cflags guile-@value{EFFECTIVE-VERSION}` -c myguile.c -o myguile.o
+gcc image-type.o myguile.o `pkg-config --libs guile-@value{EFFECTIVE-VERSION}` -o myguile
 zwingli:example-smob$ ./myguile
 guile> make-image
 #<primitive-procedure make-image>
@@ -667,7 +661,7 @@ guile> i
 guile> (clear-image i)
 guile> (clear-image 4)
 ERROR: In procedure clear-image in expression (clear-image 4):
-ERROR: Wrong type argument in position 1: 4
+ERROR: Wrong type (expecting image): 4
 ABORT: (wrong-type-arg)
  
 Type "(backtrace)" to get more information.