[plt-dev] Async channels and GC

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Jan 8 17:30:28 EST 2010

The thread for an async channel can't be collected until it's blocked
on synchronization. The thread is created by `make-asynch-channel', but
it typically doesn't run right away. That is, there's a race condition
in your test program between the last call to `collect-garbage' and the
async-channel thread reaching its sync point.

If you add a

 (sync (system-idle-evt))

after, say, `(report-items 'clear)', then the main thread waits until
the aysnc-channel thread is blocked. After that, garbage collection can
clean up the thread.


  (custodian-shutdown-all (current-custodian))

after `(report-items 'clear)' should also allow the thread to be GC'd.
Putting that earlier, however, doesn't let the thread get GC'd until
after `chn' is cleared. The asynch-channel thread is reliably suspended
by shutting down the custodian, but it's not destroyed, because the
thread inside an asynch channel is created with
`thread/suspend-to-kill' to make the channel kill-safe.

The context printed in your example will certainly not be
deterministic, since that's a race between the asynch-channel thread
and getting that thread's context. Using -j affects the stack trace,
but in a way that is difficult to pin down as either better or worse.
Using `errortrace' doesn't affect the result of from the built-in
`continuation-mark-set->context' function; instead, `errortrace'
provides improved source locations through an orthogonal set of
continuation marks, and those marks are consulted by a error handler
that `errortrace' installs.

So, I think you're seeing the intended behavior, but it's a subtle and
interesting example.

At Tue, 05 Jan 2010 02:07:30 +0100, Jakub Piotr Cłapa wrote:
> On 09-12-20 16:40, Matthew Flatt wrote:
> > That was a leak. The implementation of `scheme/async-channel' uses
> > `thread-resume', which created a strong link from its first argument to
> > its second argument. The link should be weak if the thread is blocked
> > in some way other than being explicitly suspended.
> >
> > The bug fixed is now fix in SVN.
> >
> > Thanks for the report!
> The reports are easy, your quick fixes are what the world (myself 
> included) is thankful for. :)
> The memory usage in is much better but unfortunatelly it seams 
> it is still leaking the async-channel manager threads. As far as I 
> understand the thread should go away together with the channel but it 
> somehow escapes the garbage collection (and maybe even a custodian 
> shutdown? I have not yet tried to verify this). Please check the 
> test-case attached below.
> PS. The continuation-mark-set->context output changes between runs in 
> DrScheme and mzscheme. Even adding "-l errortace -j" to the mzscheme 
> command line does not make the context appear deterministically. 
> (Un)fortunately the extracted context is not very interesting in either 
> case.
> -- 
> regards,
> Jakub Piotr Cłapa

Posted on the dev mailing list.