~ chicken-core (chicken-5) 8f2e4da74da59fbfe558f80e13fc19ee29a821ee
commit 8f2e4da74da59fbfe558f80e13fc19ee29a821ee Author: felix <felix@call-with-current-continuation.org> AuthorDate: Thu Aug 1 16:51:31 2013 +0200 Commit: Peter Bex <peter.bex@xs4all.nl> CommitDate: Fri Aug 2 19:05:27 2013 +0200 Fixes "on-exit": previously calls to "exit" inside an on-exit handler would loop endlessly. Signed-off-by: Peter Bex <peter.bex@xs4all.nl> diff --git a/library.scm b/library.scm index 7b5c61ba..e01e8688 100644 --- a/library.scm +++ b/library.scm @@ -34,6 +34,7 @@ current-print-length setter-tag read-marks ##sys#print-exit ##sys#format-here-doc-warning + exit-in-progress maximal-string-length) (not inline ##sys#user-read-hook ##sys#error-hook ##sys#signal-hook ##sys#schedule ##sys#default-read-info-hook ##sys#infix-list-hook ##sys#sharp-number-hook @@ -3957,17 +3958,17 @@ EOF (lambda () ((##sys#exit-handler) _ex_software)) ) ) +(define exit-in-progress #f) + (define exit-handler (make-parameter - (lambda code - (##sys#cleanup-before-exit) - (##core#inline - "C_exit_runtime" - (if (null? code) - 0 - (let ([code (car code)]) - (##sys#check-exact code) - code) ) ) ) ) ) + (lambda (#!optional (code 0)) + (##sys#check-exact code) + (cond (exit-in-progress + (##sys#warn "\"exit\" called while processing on-exit tasks")) + (else + (##sys#cleanup-before-exit) + (##core#inline "C_exit_runtime" code)))))) (define implicit-exit-handler (make-parameter @@ -3980,19 +3981,25 @@ EOF (define force-finalizers (make-parameter #t)) -(define ##sys#cleanup-before-exit - (lambda () - (when (##sys#fudge 37) - (##sys#print "\n" #f ##sys#standard-error) - (##sys#dump-heap-state)) - (when (##sys#fudge 13) - (##sys#print "[debug] forcing finalizers...\n" #f ##sys#standard-error) ) - (when (force-finalizers) (##sys#force-finalizers)) ) ) +(define ##sys#cleanup-tasks '()) + +(define (##sys#cleanup-before-exit) + (set! exit-in-progress #t) + (when (##sys#fudge 37) ; -:H given? + (##sys#print "\n" #f ##sys#standard-error) + (##sys#dump-heap-state)) + (let loop () + (let ((tasks ##sys#cleanup-tasks)) + (set! ##sys#cleanup-tasks '()) + (unless (null? tasks) + (for-each (lambda (t) (t)) tasks) + (loop)))) + (when (##sys#fudge 13) ; debug mode + (##sys#print "[debug] forcing finalizers...\n" #f ##sys#standard-error) ) + (when (force-finalizers) (##sys#force-finalizers)) ) (define (on-exit thunk) - (set! ##sys#cleanup-before-exit - (let ((old ##sys#cleanup-before-exit)) - (lambda () (old) (thunk)) ) ) ) + (set! ##sys#cleanup-tasks (cons thunk ##sys#cleanup-tasks))) ;;; Condition handling:Trap