* Also document *INIT-HOOKS* and *SAVE-HOOKS*.
* Trailing whitespace cleanup in start-stop.texinfo.
;;;; -*- coding: utf-8; -*-
changes in sbcl-1.0.14 relative to sbcl-1.0.13:
+ * new feature: SB-EXT:*EXIT-HOOKS* are called when the process exits
+ (see documentation for details.)
* Revived support for OpenBSD (contributed by Josh Elsasser)
* bug fix: RESOLVE-CONFLICT (and the other name conflict machinery)
is now actually exported from SB-EXT as documented. (reported by
@chapter Starting and Stopping
@menu
-* Starting SBCL::
-* Stopping SBCL::
-* Command Line Options::
-* Initialization Files::
+* Starting SBCL::
+* Stopping SBCL::
+* Command Line Options::
+* Initialization Files::
+* Initialization and Exit Hooks::
@end menu
@node Starting SBCL
@section Starting SBCL
@menu
-* Running from Shell::
-* Running from Emacs::
-* Shebang Scripts::
+* Running from Shell::
+* Running from Emacs::
+* Shebang Scripts::
@end menu
@node Running from Shell
@section Stopping SBCL
@menu
-* Quit::
+* Quit::
* End of File::
-* Saving a Core Image::
+* Saving a Core Image::
* Exit on Errors::
@end menu
SBCL has the ability to save its state as a file for later
execution. This functionality is important for its bootstrapping
-process, and is also provided as an extension to the user.
+process, and is also provided as an extension to the user.
@include fun-sb-ext-save-lisp-and-die.texinfo
+@include var-sb-ext-star-save-hooks-star.texinfo
To facilitate distribution of SBCL applications using external
resources, the filesystem location of the SBCL core file being used is
runtime system or the Lisp system.
@menu
-* Runtime Options::
-* Toplevel Options::
+* Runtime Options::
+* Toplevel Options::
@end menu
@node Runtime Options
can be used to customize the lisp environment.
@menu
-* System Initialization File::
-* User Initialization File::
-* Initialization File Semantics::
-* Initialization Examples::
+* System Initialization File::
+* User Initialization File::
+* Initialization File Semantics::
+* Initialization Examples::
@end menu
@node System Initialization File
files follow.
@menu
-* Unix-style Command Line Protocol::
-* Automatic Recompilation of Stale Fasls::
+* Unix-style Command Line Protocol::
+* Automatic Recompilation of Stale Fasls::
@end menu
@node Unix-style Command Line Protocol
@lisp
;;; If the first user-processable command-line argument is a filename,
;;; disable the debugger, load the file handling shebang-line and quit.
-(let ((script (and (second *posix-argv*)
+(let ((script (and (second *posix-argv*)
(probe-file (second *posix-argv*)))))
(when script
;; Handle shebang-line
(declare (ignore char arg))
(read-line stream)))
;; Disable debugger
- (setf *invoke-debugger-hook*
+ (setf *invoke-debugger-hook*
(lambda (condition hook)
(declare (ignore hook))
;; Uncomment to get backtraces on errors
@lisp
(require :asdf)
-;;; If a fasl was stale, try to recompile and load (once).
-(defmethod asdf:perform :around ((o asdf:load-op)
+;;; If a fasl was stale, try to recompile and load (once).
+(defmethod asdf:perform :around ((o asdf:load-op)
(c asdf:cl-source-file))
(handler-case (call-next-method o c)
;; If a fasl was stale, try to recompile and load (once).
(asdf:perform (make-instance 'asdf:compile-op) c)
(call-next-method))))
@end lisp
+
+@node Initialization and Exit Hooks
+@comment node-name, next, previous, up
+@section Initialization and Exit Hooks
+
+SBCL provides hooks into the system initialization and exit.
+
+@include var-sb-ext-star-init-hooks-star.texinfo
+@include var-sb-ext-star-exit-hooks-star.texinfo
+
"*DEBUG-PRINT-VARIABLE-ALIST*"
;; Hooks into init & save sequences
- "*INIT-HOOKS*" "*SAVE-HOOKS*"
+ "*INIT-HOOKS*" "*SAVE-HOOKS*" "*EXIT-HOOKS*"
;; There is no one right way to report progress on
;; hairy compiles.
;; name to the string if possible
"BLOCK-GENSYM"
+ ;; Calling a list of hook functions, plus error handling.
+ "CALL-HOOKS"
+
;; Constant form evaluation
"CONSTANT-FORM-VALUE"
"CONSTANT-TYPEP"
(defun quit (&key recklessly-p (unix-status 0))
#!+sb-doc
- "Terminate the current Lisp. Things are cleaned up (with
-UNWIND-PROTECT and so forth) unless RECKLESSLY-P is non-NIL. On
-UNIX-like systems, UNIX-STATUS is used as the status code."
+ "Terminate the current Lisp. *EXIT-HOOKS* are pending unwind-protect
+cleanup forms are run unless RECKLESSLY-P is true. On UNIX-like
+systems, UNIX-STATUS is used as the status code."
(declare (type (signed-byte 32) unix-status))
+ ;; FIXME: Windows is not "unix-like", but still has the same
+ ;; unix-status... maybe we should just revert to calling it :STATUS?
(/show0 "entering QUIT")
(if recklessly-p
(sb!unix:unix-exit unix-status)
;; re-disable ldb again.
(when (eq *invoke-debugger-hook* 'sb!debug::debugger-disabled-hook)
(sb!debug::disable-debugger))
- (dolist (hook *init-hooks*)
- (with-simple-restart (continue "Skip this initialization hook.")
- (funcall hook))))
+ (call-hooks "initialization" *init-hooks*))
\f
;;;; some support for any hapless wretches who end up debugging cold
;;;; init code
;; for finalizers and after-gc hooks.
(when (sb!thread:thread-alive-p sb!thread:*current-thread*)
(run-pending-finalizers)
- (dolist (hook *after-gc-hooks*)
- (handler-case
- (funcall hook)
- (serious-condition (c)
- (warn "Error calling after-GC hook ~S:~% ~A" hook c)))))))))
+ (call-hooks "after-GC" *after-gc-hooks* :on-error :warn))))))
;;; This is the user-advertised garbage collection function.
(defun gc (&key (gen 0) (full nil) &allow-other-keys)
(def %compare-and-swap-symbol-plist (symbol) symbol-plist)
(def %compare-and-swap-symbol-value (symbol) symbol-value)
(def %compare-and-swap-svref (vector index) svref))
+
+(defun call-hooks (kind hooks &key (on-error :error))
+ (dolist (hook hooks)
+ (handler-case
+ (funcall hook)
+ (serious-condition (c)
+ (if (eq :warn on-error)
+ (warn "Problem running ~A hook ~S:~% ~A" kind hook c)
+ (with-simple-restart (continue "Skip this ~A hook." kind)
+ (error "Problem running ~A hook ~S:~% ~A" kind hook c)))))))
(save-core t)))))
(defun deinit ()
- (dolist (hook *save-hooks*)
- (with-simple-restart (continue "Skip this save hook.")
- (funcall hook)))
+ (call-hooks "save" *save-hooks*)
(when (rest (sb!thread:list-all-threads))
(error "Cannot save core with multiple threads running."))
(float-deinit)
been initialized. Unused by SBCL itself: reserved for user and
applications.")
+(defvar *exit-hooks* nil
+ #!+sb-doc
+ "This is a list of functions which are called in an unspecified
+order when SBCL process exits. Unused by SBCL itself: reserved for
+user and applications. Using (QUIT :RECKLESSLY-P T), or calling
+exit(3) directly will circumvent these hooks.")
+
\f
;;; Binary search for simple vectors
(defun binary-search (value seq &key (key #'identity))
(with-unique-names (caught)
`(let ((,caught (catch '%end-of-the-world
(/show0 "inside CATCH '%END-OF-THE-WORLD")
- ,@body)))
+ (unwind-protect
+ (progn ,@body)
+ (call-hooks "exit" *exit-hooks*)))))
(/show0 "back from CATCH '%END-OF-THE-WORLD, flushing output")
(flush-standard-output-streams)
(sb!thread::terminate-session)
;;; 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".)
-"1.0.13.19"
+"1.0.13.20"