cs & threads: fix weak reference from custodian

Using a will executor to turn a reference from weak to strong still
seems like an ok idea, but it needs to be a regular will executor,
because a custodian-registered value is likely to involve have a
nested self-reference.
This commit is contained in:
Matthew Flatt 2019-05-25 17:26:41 -06:00
parent f70b776831
commit f0c39b1f81
4 changed files with 24 additions and 11 deletions

View File

@ -149,6 +149,12 @@
'path->main-lib-relative
'main-lib-relative->path))
;; For checking and debugging memory leaks; set `PLT_SETUP_DMS_ARGS`
;; to an S-expression list and use `-j 1` to run a non-parallel setup:
(define post-collection-dms-args
(let ([v (getenv "PLT_SETUP_DMS_ARGS")])
(and v (read (open-input-string v)))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Errors ;;
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -1087,6 +1093,9 @@
#:managed-compile-zo caching-managed-compile-zo
#:skip-path (and (avoid-main-installation) main-collects-dir)
#:skip-doc-sources? (not make-docs?))))))
(when post-collection-dms-args
(collect-garbage)
(apply dump-memory-stats post-collection-dms-args))
(if (eq? 0 gcs)
0
(begin (collect-garbage) (sub1 gcs))))

View File

@ -293,12 +293,11 @@
[(eq? 'metacontinuation-frame (car args))
metacontinuation-frame?]
[(symbol? (car args))
#f
;; This is disaterously slow, so don't try it:
#;
(let ([type (car args)])
(let ([name (car args)])
(lambda (o)
(eq? ((inspect/object o) 'type) type)))]
(and (#%record? o)
(let ([rtd (#%record-rtd o)])
(eq? name (#%record-type-name rtd))))))]
[else #f])
;; 'new mode for backtrace?
(and (pair? args)

View File

@ -9,7 +9,7 @@
;; lifo. The `will-stacks` tables map a finalized value to a list
;; of finalizers, where each finalizer is an ephemeron pairing a will
;; executor with a will function (so that the function is not retained
;; if the will executor is dropped)
;; if the will executor is dropped).
(define-thread-local the-will-stacks (make-weak-eq-hashtable))
(define-thread-local the-late-will-stacks (make-weak-eq-hashtable))
@ -36,7 +36,7 @@
(check who (procedure-arity-includes/c 1) proc)
(disable-interrupts)
(let ([l (hashtable-ref (will-executor-will-stacks executor) v '())]
;; By using an ephemeron pair, if the excutor becomes
;; By using an ephemeron pair, if the executor becomes
;; unreachable, then we can drop the finalizer procedure. That
;; pattern prevents unbreakable cycles by an untrusted process
;; that has no access to a will executor that outlives the
@ -79,7 +79,8 @@
(let ([v (guardian)])
(when v
(let we-loop ([l (hashtable-ref will-stacks v '())])
(when (pair? l)
(cond
[(pair? l)
(let* ([e+proc (car l)]
[e (car e+proc)]
[proc (cdr e+proc)]
@ -101,7 +102,9 @@
(when (will-executor-keep? e)
;; Ensure that a late will executor stays live
;; in this place as long as there are wills to execute
(hashtable-set! late-will-executors-with-pending e #t))]))))
(hashtable-set! late-will-executors-with-pending e #t))]))]
[else
(hashtable-delete! will-stacks v)]))
(loop)))))
(define (poll-will-executors)

View File

@ -112,7 +112,7 @@
[(custodian-shut-down? cust) #f]
[else
(define we (and (not weak?)
(host:make-late-will-executor void #f)))
(host:make-will-executor void)))
(hash-set! (custodian-children cust)
obj
(cond
@ -123,7 +123,9 @@
;; Registering with a will executor that we retain but never
;; poll has the effect of turning a semi-weak reference
;; (allows other finalizers, but doesn't clear weak boxes)
;; into a strong one when there are no other references:
;; into a strong one when there are no other references;
;; we're assuming that no wills were previously registered
;; so that this one is last on the stack of wills:
(host:will-register we obj void))
(when gc-root?
(host:disable-interrupts)