fix sync
on inaccessible place channel
Commit 5ea4c2ab68
broke GCing of a thread that is blocked
via `sync` (as opposed to `place-channel-get`) on a place
channel whose write end is inaccessible.
This commit is contained in:
parent
03a82e21b5
commit
04a60d713b
|
@ -421,27 +421,30 @@
|
|||
;; can be GCed if the other end of the channel is
|
||||
;; unreachable --- where a place's channels should
|
||||
;; all count as "unreachable" when the place ends
|
||||
(displayln "checking place-channel and thread GC interaction")
|
||||
(let ([N 40])
|
||||
(define weaks (make-weak-hash))
|
||||
(for ([i (in-range N)])
|
||||
(define s (make-semaphore))
|
||||
(hash-set!
|
||||
weaks
|
||||
(thread (lambda ()
|
||||
(define-values (i o) (place-channel))
|
||||
(define p (place ch (place-channel-get ch)))
|
||||
(place-channel-put p o)
|
||||
(place-wait p)
|
||||
(semaphore-post s)
|
||||
(sync i)))
|
||||
#t)
|
||||
(sync s))
|
||||
(for ([i 3])
|
||||
(sync (system-idle-evt))
|
||||
(collect-garbage))
|
||||
(unless ((hash-count weaks) . < . (/ N 2))
|
||||
(error "thread-gc test failed")))
|
||||
(define (check-thread sync-ch)
|
||||
(displayln "checking place-channel and thread GC interaction")
|
||||
(let ([N 40])
|
||||
(define weaks (make-weak-hash))
|
||||
(for ([i (in-range N)])
|
||||
(define s (make-semaphore))
|
||||
(hash-set!
|
||||
weaks
|
||||
(thread (lambda ()
|
||||
(define-values (i o) (place-channel))
|
||||
(define p (place ch (place-channel-get ch)))
|
||||
(place-channel-put p o)
|
||||
(place-wait p)
|
||||
(semaphore-post s)
|
||||
(sync-ch i)))
|
||||
#t)
|
||||
(sync s))
|
||||
(for ([i 3])
|
||||
(sync (system-idle-evt))
|
||||
(collect-garbage))
|
||||
(unless ((hash-count weaks) . < . (/ N 2))
|
||||
(error "thread-gc test failed"))))
|
||||
(check-thread place-channel-get)
|
||||
(check-thread sync)
|
||||
|
||||
)
|
||||
|
||||
|
|
|
@ -3547,7 +3547,14 @@ static int place_channel_ready(Scheme_Object *so, Scheme_Schedule_Info *sinfo) {
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (no_writers) {
|
||||
/* block on a semaphore that is not accessible, which may allow the thread
|
||||
to be GCed */
|
||||
scheme_set_sync_target(sinfo, scheme_make_sema(0), scheme_void, NULL, 0, 0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user