[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-hackers] [PATCH] Fix couple of hangs related to finalizers
From: |
megane |
Subject: |
Re: [Chicken-hackers] [PATCH] Fix couple of hangs related to finalizers and (gc #t) |
Date: |
Sat, 10 Aug 2019 08:04:31 +0300 |
User-agent: |
mu4e 1.0; emacs 25.1.1 |
megane <address@hidden> writes:
>
> Also signal an error if trying to re-enter. This also would cause an
> infinite loop (when calling (gc #t) inside a finalizer). It would
> need special handling if re-entry is to be supported.
This is too aggressive. The call from ##sys#interrupt-hook should still
go through without errors. (Think about the case when the thread running
finalizers gets an interrupt.)
Attached is a version that doesn't error when re-entering from
##sys#interrupt-hook.
>From 7bad7768da90ca8cf9b05c1b7779518c747f38f8 Mon Sep 17 00:00:00 2001
From: megane <address@hidden>
Date: Fri, 9 Aug 2019 13:39:36 +0300
Subject: [PATCH] Fix couple of hangs related to finalizers and (gc #t)
Calling (gc #t) would get into an infinite no-progress loop in
was being run in another thread.
In that case the (##sys#run-pending-finalizers #f) call in
is compiled with interrupts disabled the other thread never got to run
again.
* library.scm (##sys#run-pending-finalizers): Yield the current thread
if pending finalizers are being run in another thread.
Also signal an error if trying to re-enter without "state". This
also would cause an infinite loop (when calling (gc #t) inside a
finalizer). It would need special handling if re-entry is to be
supported.
Fixes #1586
---
library.scm | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/library.scm b/library.scm
index bc0ef42c..ed508068 100644
--- a/library.scm
+++ b/library.scm
@@ -6072,10 +6072,11 @@ static C_word C_fcall C_setenv(C_word x, C_word y) {
(define ##sys#run-pending-finalizers
(let ((vector-fill! vector-fill!)
(string-append string-append)
- (working #f) )
+ (working-thread #f) )
(lambda (state)
- (unless working
- (set! working #t)
+ (cond
+ ((not working-thread)
+ (set! working-thread ##sys#current-thread)
(let* ((c (##sys#slot ##sys#pending-finalizers 0)) )
(when (##sys#debug-mode?)
(##sys#print
@@ -6097,7 +6098,15 @@ static C_word C_fcall C_setenv(C_word x, C_word y) {
(##sys#slot ##sys#pending-finalizers i2)) ) ))
(vector-fill! ##sys#pending-finalizers (##core#undefined))
(##sys#setislot ##sys#pending-finalizers 0 0)
- (set! working #f) ) )
+ (set! working-thread #f)))
+ (state)
+ ((eq? working-thread ##sys#current-thread)
+ (##sys#signal-hook
+ #:error '##sys#run-pending-finalizers
+ "re-entry from finalizer thread (maybe (gc #t) was called from a
finalizer)"))
+ (else
+ ;; Give finalizer thread a change to run
+ (##sys#thread-yield!)))
(cond ((not state))
((procedure? state) (state))
(state (##sys#context-switch state) ) ) ) ))
--
2.17.1