0.8.21.31: tweak finalizers, thighten spec further
authorNikodemus Siivola <nikodemus@random-state.net>
Sun, 10 Apr 2005 12:55:54 +0000 (12:55 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Sun, 10 Apr 2005 12:55:54 +0000 (12:55 +0000)
 * sprinkle WITHOUT-GCING around, so that we won't enter GC while
    holding the lock on finalizer store.
 * specify that finalizers run in an unpredictable dynamic scope and
    must be fully re-entrant. Add a few examples for good measure.
 * add finalizer, weak pointer, and after gc hook documentation to the
    manual.

NEWS
doc/manual/beyond-ansi.texinfo
src/code/final.lisp
src/code/weak.lisp
version.lisp-expr

diff --git a/NEWS b/NEWS
index 041ea38..b85bd54 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,8 +6,10 @@ changes in sbcl-0.8.22 relative to sbcl-0.8.21:
     interrupts enabled.
   * incompatible change: support for *BEFORE-GC-HOOKS* (that have been
     inoperational for a while now) has been completely removed.
-  * Null lexical environments are now printed as #<NULL-LEXENV>, 
+  * null lexical environments are now printed as #<NULL-LEXENV>, 
     significantly reducing the amount of clutter in typical backtraces.
+  * documentation on weak pointers, finalization, and after GC hooks
+    has been added to the manual.
   * optimization: REPLACE on declared (UNSIGNED-BYTE 8) vectors, as well
     as other specialized array types, is much faster.  SUBSEQ and
     COPY-SEQ on such arrays have also been sped up.
index a0bffa2..4bb8556 100644 (file)
@@ -7,36 +7,38 @@ ANSI standard. SBCL doesn't support as many extensions as CMUCL, but
 it still has quite a few.  @xref{Contributed Modules}.
 
 @menu
-* Things Which Might Be In The Next ANSI Standard::  
+* Garbage Collection::          
+* Metaobject Protocol::         
 * Support For Unix::            
 * Customization Hooks for Users::  
 * Tools To Help Developers::    
-* Resolution of Name Conflicts::
+* Resolution of Name Conflicts::  
 * Stale Extensions::            
 * Efficiency Hacks::            
 @end menu
 
-@node  Things Which Might Be In The Next ANSI Standard
+@node  Garbage Collection
 @comment  node-name,  next,  previous,  up
-@section Things Which Might Be In The Next ANSI Standard
-
-SBCL provides extensive support for calling external C code,
-@ref{Foreign Function Interface}.
+@section Garbage Collection
 
 SBCL provides additional garbage collection functionality not
 specified by ANSI. Weak pointers allow references to objects to be
-maintained without keeping them from being GCed (garbage
-collected). And ``finalization'' hooks are available to cause code to
-be executed when an object has been GCed.
-@c <!-- FIXME: Actually documenting these would be good.:-| -->
-
-SBCL supports @dfn{Gray streams}, user-overloadable CLOS classes whose
-instances can be used as Lisp streams (e.g. passed as the first
-argument to @code{format}).  Additionally, the bundled contrib module
-@dfn{sb-simple-streams} implements a subset of the Franz Allegro
-simple-streams proposal.
-
-SBCL supports a MetaObject Protocol which is intended to be compatible
+maintained without keeping them from being garbage collected, and
+``finalization'' hooks are available to cause code to be executed when
+an object has been garbage collected. Additionally users can specify
+their own cleanup actions to be executed with garbage collection.
+
+@include fun-sb-ext-finalize.texinfo
+@include fun-sb-ext-cancel-finalization.texinfo
+@include fun-sb-ext-make-weak-pointer.texinfo
+@include fun-sb-ext-weak-pointer-value.texinfo
+@include var-sb-ext-star-after-gc-hooks-star.texinfo
+
+@node Metaobject Protocol
+@comment  node-name,  next,  previous,  up
+@section Metaobject Protocol
+
+SBCL supports a metaobject protocol which is intended to be compatible
 with AMOP; present exceptions to this (as distinct from current bugs)
 are:
 
index a2adcaf..945cd5e 100644 (file)
 (defun finalize (object function)
   #!+sb-doc 
   "Arrange for the designated FUNCTION to be called when there
-are no more references to OBJECT. In a multithreaded environment
-the finalizer may run in any thread."
-  (sb!thread:with-mutex (*finalizer-store-lock*)
-    (push (cons (make-weak-pointer object) function)
-         *finalizer-store*))
+are no more references to OBJECT, including references in
+FUNCTION itself.
+
+In a multithreaded environment FUNCTION may be called in any
+thread. In both single and multithreaded environments FUNCTION
+may be called in any dynamic scope: consequences are unspecified
+if FUNCTION is not fully re-entrant.
+
+Errors from FUNCTION are handled and cause a WARNING to be
+signalled in whichever thread the FUNCTION was called in.
+
+Examples:
+
+  ;;; good
+  (let* ((handle (get-handle))
+         (object (make-object handle)))
+   ;; assumes RELEASE-HANDLE is re-entrant
+   (finalize object (lambda () (release-handle handle)))
+   object)
+
+  ;;; bad, finalizer refers to object being finalized, causing
+  ;;; it to be retained indefinitely
+  (let* ((handle (get-handle))
+         (object (make-object handle)))
+    (finalize object (lambda () (release-handle (object-handle object)))))
+
+  ;;; bad, not re-entrant
+  (defvar *rec* nil)
+
+  (defun oops ()
+   (when *rec* 
+     (error \"recursive OOPS\"))
+   (let ((*rec* t))
+     (gc))) ; or just cons enough to cause one
+
+  (progn 
+    (finalize \"oops\" #'oops)
+    (oops)) ; causes GC and re-entry to #'oops due to the finalizer
+            ; -> ERROR, caught, WARNING signalled"
+  (sb!sys:without-gcing
+      (sb!thread:with-mutex (*finalizer-store-lock*)
+       (push (cons (make-weak-pointer object) function)
+             *finalizer-store*)))
   object)
 
 (defun cancel-finalization (object)
@@ -32,22 +70,24 @@ the finalizer may run in any thread."
   ;; Check for NIL to avoid deleting finalizers that are waiting to be
   ;; run.
   (when object
-    (sb!thread:with-mutex (*finalizer-store-lock*)
-      (setf *finalizer-store*
-           (delete object *finalizer-store*
-                   :key (lambda (pair) 
-                          (weak-pointer-value (car pair))))))
+    (sb!sys:without-gcing
+       (sb!thread:with-mutex (*finalizer-store-lock*)
+         (setf *finalizer-store*
+               (delete object *finalizer-store*
+                       :key (lambda (pair) 
+                              (weak-pointer-value (car pair)))))))
     object))
 
 (defun run-pending-finalizers ()
   (let (pending)
-    (sb!thread:with-mutex (*finalizer-store-lock*)
-      (setf *finalizer-store*
-           (delete-if  (lambda (pair)
-                         (when (null (weak-pointer-value (car pair)))
-                           (push (cdr pair) pending)
-                           t))
-                     *finalizer-store*)))
+    (sb!sys:without-gcing
+       (sb!thread:with-mutex (*finalizer-store-lock*)
+         (setf *finalizer-store*
+               (delete-if  (lambda (pair)
+                             (when (null (weak-pointer-value (car pair)))
+                               (push (cdr pair) pending)
+                               t))
+                           *finalizer-store*))))
     ;; We want to run the finalizer bodies outside the lock in case
     ;; finalization of X causes finalization to be added for Y.
     (dolist (fun pending)
index 37b83a1..7268b38 100644 (file)
 (defun make-weak-pointer (object)
   #!+sb-doc
   "Allocate and return a weak pointer which points to OBJECT."
-  (declare (values weak-pointer))
   (make-weak-pointer object))
 
 #!-sb-fluid (declaim (inline weak-pointer-value))
 (defun weak-pointer-value (weak-pointer)
   #!+sb-doc
   "If WEAK-POINTER is valid, return the value of WEAK-POINTER and T.
-   If the referent of WEAK-POINTER has been garbage collected, returns
-   the values NIL and NIL."
-  (declare (type weak-pointer weak-pointer)
-          (values t (member t nil)))
+If the referent of WEAK-POINTER has been garbage collected,
+returns the values NIL and NIL."
+  (declare (type weak-pointer weak-pointer))
   ;; We don't need to wrap this with a WITHOUT-GCING, because once we
   ;; have extracted the value, our reference to it will keep the weak
   ;; pointer from becoming broken. We just have to make sure the
index a795dd1..c29142b 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.21.30"
+"0.8.21.31"