[racket] the benefactor in THREAD-RESUME

From: Taylor R Campbell (campbell+racket at mumble.net)
Date: Sun Nov 7 21:38:02 EST 2010

   Date: Sun, 7 Nov 2010 19:01:40 -0700
   From: Matthew Flatt <mflatt at cs.utah.edu>

   Here's the only potential problem that I see offhand. Imagine that
   there are multiple `sync' steps in communicating with `t'. The relevant
   events for each `sync' must be protected using
   `with-thread-resume-evt', which means that the programmer who is making
   the current thread and `t' communicate must see all the relevant
   `sync's. The `sync's can't be hidden inside some other abstraction.

If there are multiple rendezvous with thread t, shouldn't it be enough
to use WITH-THREAD-RESUMED?

(with-thread-resumed t
  (lambda ()
    (channel-send c x)
    ;; versus (sync (with-thread-resumed-evt t (channel-send-evt c x)))
    (something-that-synchronizes-without-exposing-an-evt)
    (case (channel-receive c*)
      ...)))

Or do I misunderstand the problem?

   FWIW, by "until the sync operation commits" I imagine you mean that if
   the thread that called `sync' is itself suspended, then the resumed
   thread might be suspended as well, even though the sync hasn't
   committed --- and that's still ok for the cases I can think of.

Yes.

A little more generally, I wonder whether there are any situations in
which a thread t suddenly decides that it must be a benefactor of
another thread u for the rest t's life, or whether there is always a
time beyond which t needn't care about u[*]. Also, I wonder whether
there is any danger -- a hard-to-understand resource leak, say -- to
t's being a benefactor longer than necessary.

[*] It may be that t needs u for the whole of t's life from start to
    end, but in that case, t could just run entirely inside a
    (with-thread-resumed u (lambda () ...)).  So I'm asking only about
    mid-life crises -- when t decides to be a benefactor in some
    library routine that it happens to call, for instance.


Posted on the users mailing list.