Ticket #866: 0001-Catch-exceptions-in-finalizers-and-added-tests.patch
File 0001-Catch-exceptions-in-finalizers-and-added-tests.patch, 8.0 KB (added by , 12 years ago) |
---|
-
chicken.h
From fcadbb82750d10d0c01178ffe603d9b5cfcf1731 Mon Sep 17 00:00:00 2001 From: felix <felix@call-with-current-continuation.org> Date: Thu, 14 Jun 2012 09:34:25 +0200 Subject: [PATCH] Catch exceptions in finalizers and added tests. Resizing of the finalizer-table has been removed. There can be at most 4096 live finalizers (can be changed by using -:f). --- chicken.h | 1 - distribution/manifest | 1 + library.scm | 49 ++++++++++++++++++++++++++++----------- runtime.c | 14 ----------- scheduler.scm | 47 ++++++++++++++----------------------- tests/finalizer-error-test.scm | 17 ++++++++++++++ tests/runtests.sh | 4 +- 7 files changed, 73 insertions(+), 60 deletions(-) create mode 100644 tests/finalizer-error-test.scm diff --git a/chicken.h b/chicken.h index 837a51c..62dd1bc 100644
a b C_fctexport void C_fcall C_paranoid_check_for_interrupt(void) C_regparm; 1563 1563 C_fctexport void C_zap_strings(C_word str); 1564 1564 C_fctexport void C_set_or_change_heap_size(C_word heap, int reintern); 1565 1565 C_fctexport void C_do_resize_stack(C_word stack); 1566 C_fctexport C_word C_resize_pending_finalizers(C_word size);1567 1566 C_fctexport void C_initialize_lf(C_word *lf, int count); 1568 1567 C_fctexport void *C_register_lf(C_word *lf, int count); 1569 1568 C_fctexport void *C_register_lf2(C_word *lf, int count, C_PTABLE_ENTRY *ptable); -
distribution/manifest
diff --git a/distribution/manifest b/distribution/manifest index 6c02c34..02bc6ec 100644
a b tests/functor-tests.scm 189 189 tests/square-functor.scm 190 190 tests/use-square-functor.scm 191 191 tests/pp-test.scm 192 tests/finalizer-error-test.scm 192 193 tests/reverser/tags/1.0/reverser.meta 193 194 tests/reverser/tags/1.0/reverser.setup 194 195 tests/reverser/tags/1.0/reverser.scm -
library.scm
diff --git a/library.scm b/library.scm index 030fad8..3387924 100644
a b EOF 4574 4574 (define set-finalizer! 4575 4575 (lambda (x y) 4576 4576 (when (fx> (##sys#fudge 26) _max_pending_finalizers) 4577 (if (##core#inline "C_resize_pending_finalizers" (fx* 2 _max_pending_finalizers)) 4578 (begin 4579 (set! ##sys#pending-finalizers (##sys#grow-vector ##sys#pending-finalizers 4580 (fx+ (fx* 2 _max_pending_finalizers) 1) 4581 (##core#undefined))) 4582 (when (##sys#fudge 13) 4583 (print "[debug] too many finalizers (" (##sys#fudge 26) 4584 "), resized max finalizers to " _max_pending_finalizers "...") ) ) 4585 (begin 4586 (when (##sys#fudge 13) 4587 (print "[debug] too many finalizers (" (##sys#fudge 26) "), forcing ...") ) 4588 (##sys#force-finalizers) ) ) ) 4577 (when (##sys#fudge 13) 4578 (print "[debug] too many finalizers (" (##sys#fudge 26) "), forcing ...") ) 4579 (##sys#force-finalizers) 4580 (when (fx> (##sys#fudge 26) _max_pending_finalizers) 4581 (##sys#signal-hook 4582 #:memory-error 'set-finalizer! 4583 "maximal finalizer-count exceeded"))) 4589 4584 (##sys#set-finalizer! x y) ) ) 4590 4585 4591 4586 (define ##sys#run-pending-finalizers … … EOF 4601 4596 (do ([i 0 (fx+ i 1)]) 4602 4597 ((fx>= i c)) 4603 4598 (let ([i2 (fx+ 1 (fx* i 2))]) 4604 ((##sys#slot ##sys#pending-finalizers (fx+ i2 1)) 4605 (##sys#slot ##sys#pending-finalizers i2)) ) ) 4599 (handle-exceptions ex 4600 (##sys#show-exception-warning ex "in finalizer" #f) 4601 ((##sys#slot ##sys#pending-finalizers (fx+ i2 1)) 4602 (##sys#slot ##sys#pending-finalizers i2)) ) )) 4606 4603 (vector-fill! ##sys#pending-finalizers (##core#undefined)) 4607 4604 (##sys#setislot ##sys#pending-finalizers 0 0) 4608 4605 (set! working #f) ) ) … … EOF 4741 4738 (writeargs (list ex) port) ] ) ) ) ) ) 4742 4739 4743 4740 4741 ;;; Show exception message and backtrace as warning 4742 ;;; (used for threads and finalizers) 4743 4744 (define ##sys#show-exception-warning 4745 (let ((print-error-message print-error-message) 4746 (display display) 4747 (write-char write-char) 4748 (print-call-chain print-call-chain) 4749 (open-output-string open-output-string) 4750 (get-output-string get-output-string) ) 4751 (lambda (exn cause #!optional (thread ##sys#current-thread)) 4752 (when ##sys#warnings-enabled 4753 (let ((o (open-output-string))) 4754 (display "Warning" o) 4755 (when thread 4756 (display " (" o) 4757 (display thread o) 4758 (write-char #\) o)) 4759 (display ": " o) 4760 (display cause o) 4761 (print-error-message exn ##sys#standard-error (get-output-string o)) 4762 (print-call-chain ##sys#standard-error 0 thread) ) )))) 4763 4764 4744 4765 ;;; We need this here so `location' works: 4745 4766 4746 4767 (define (##sys#make-locative obj index weak? loc) -
runtime.c
diff --git a/runtime.c b/runtime.c index ced344b..bdaa335 100644
a b void C_check_nursery_minimum(C_word words) 1108 1108 panic(C_text("nursery is too small - try higher setting using the `-:s' option")); 1109 1109 } 1110 1110 1111 C_word C_resize_pending_finalizers(C_word size) {1112 int sz = C_num_to_int(size);1113 1114 FINALIZER_NODE **newmem =1115 (FINALIZER_NODE **)C_realloc(pending_finalizer_indices, sz * sizeof(FINALIZER_NODE *));1116 1117 if (newmem == NULL)1118 return C_SCHEME_FALSE;1119 1120 pending_finalizer_indices = newmem;1121 C_max_pending_finalizers = sz;1122 return C_SCHEME_TRUE;1123 }1124 1125 1111 1126 1112 /* Parse runtime options from command-line: */ 1127 1113 -
scheduler.scm
diff --git a/scheduler.scm b/scheduler.scm index e3a96bc..d3a2620 100644
a b EOF 309 309 (##sys#setislot t 4 #f) 310 310 (##sys#add-to-ready-queue t) ) 311 311 312 (define ##sys#default-exception-handler 313 (let ([print-error-message print-error-message] 314 [display display] 315 [print-call-chain print-call-chain] 316 [open-output-string open-output-string] 317 [get-output-string get-output-string] ) 318 (lambda (arg) 319 (let ([ct ##sys#current-thread]) 320 (dbg "exception: " ct " -> " 321 (if (##sys#structure? arg 'condition) (##sys#slot arg 2) arg)) 322 (cond [(foreign-value "C_abort_on_thread_exceptions" bool) 323 (let* ([pt ##sys#primordial-thread] 324 [ptx (##sys#slot pt 1)] ) 325 (##sys#setslot 326 pt 1 327 (lambda () 328 (##sys#signal arg) 329 (ptx) ) ) 330 (##sys#thread-unblock! pt) ) ] 331 [##sys#warnings-enabled 332 (let ([o (open-output-string)]) 333 (display "Warning (" o) 334 (display ct o) 335 (display ")" o) 336 (print-error-message arg ##sys#standard-error (get-output-string o)) 337 (print-call-chain ##sys#standard-error 0 ct) ) ] ) 338 (##sys#setslot ct 7 arg) 339 (##sys#thread-kill! ct 'terminated) 340 (##sys#schedule) ) ) ) ) 312 (define (##sys#default-exception-handler arg) 313 (let ([ct ##sys#current-thread]) 314 (dbg "exception: " ct " -> " 315 (if (##sys#structure? arg 'condition) (##sys#slot arg 2) arg)) 316 (cond ((foreign-value "C_abort_on_thread_exceptions" bool) 317 (let* ([pt ##sys#primordial-thread] 318 [ptx (##sys#slot pt 1)] ) 319 (##sys#setslot 320 pt 1 321 (lambda () 322 (##sys#signal arg) 323 (ptx) ) ) 324 (##sys#thread-unblock! pt) ) ) 325 (else 326 (##sys#show-exception-warning arg "in thread" ct))) 327 (##sys#setslot ct 7 arg) 328 (##sys#thread-kill! ct 'terminated) 329 (##sys#schedule) ) ) 341 330 342 331 343 332 ;;; `select()'-based blocking: -
new file tests/finalizer-error-test.scm
diff --git a/tests/finalizer-error-test.scm b/tests/finalizer-error-test.scm new file mode 100644 index 0000000..cf24da9
- + 1 ;;;; finalizer-error-test.scm - by "megane" 2 3 (define n 10000) 4 5 (define (make-objects n) 6 (let loop [(i 0)] 7 (let [(o (make-vector 100))] 8 ;(print "making " i) 9 (set-finalizer! o (lambda (ob) (print* " " i))) 10 (if (< i n) 11 (loop (+ 1 i)))))) 12 13 (set-finalizer! (make-vector 100) (lambda (ob) (+ i 'a))) 14 15 (make-objects n) 16 17 (print "done") -
tests/runtests.sh
diff --git a/tests/runtests.sh b/tests/runtests.sh index 9f9f7ee..323c370 100755
a b $compile symbolgc-tests.scm 341 341 342 342 echo "======================================== finalizer tests ..." 343 343 $interpret -s test-finalizers.scm 344 345 echo "======================================== finalizer tests (2) ..." 344 $compile finalizer-error-test.scm 345 ./a.out 346 346 $compile test-finalizers-2.scm 347 347 ./a.out 348 348