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:
Matthew Flatt 2014-04-29 12:56:19 -06:00
parent 03a82e21b5
commit 04a60d713b
2 changed files with 32 additions and 22 deletions

View File

@ -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)
)

View File

@ -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;
}