[racket] Callback on shutdown

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed May 7 10:19:17 EDT 2014

I've added `custodian-tidy-all` and related functions to [un]register a
"tidy callback". The default exit handler calls `custodian-tidy-all` on
the root custodian before exiting, which triggers all registered tidy
callbacks.

I found one place where I needed this before: `reencode-output-port`. A
port produced by `reencode-output-port` now installs a tidy handler to
flush output whenever its buffer is non-empty. Setting the current
output port to a reencoded port now flushes in the way you'd expect on
exit.

At Sun, 4 May 2014 17:02:59 -0600, Matthew Flatt wrote:
> I don't think the thing you want currently exists in general, although
> it exists internally for flushing output ports.
> 
> Simply triggering the exit handler when the Racket process exits
> doesn't seem like a good enough solution. It's awkward to add and
> remove callbacks by changing the exit handler, and it doesn't
> immediately address the problem of exiting sandbox-like nested
> processes. I don't have a solution that immediately addresses the
> problem of subprocesses, but if we have to revise sandbox-like things
> to support a polite exit, then I think we can find a better interface.
> 
> Maybe the right solution is to add support for atexit()-like actions on
> custodians, along with a new operation to exit a custodian (implying an
> exit for all sub-custodians). Various exit modes, including normal exit
> of the Racket process or calling the default exit handler, would use
> the custodian-exit operation before existing. Sandboxing contexts can
> be similarly improved to exit a custodian or add support for exiting,
> depending on what makes sense for the context.
> 
> Unlike shutting down a custodian, which is analogous to SIGKILL,
> exiting a custodian would be closer to SIGQUIT. Along those lines,
> where shutting down a custodian implies mandatory and atomic actions,
> exiting a custodian is a request and non-atomic --- so it would safe to
> attach arbitrary exit procedures. Of course, there's no guarantee that
> an exit procedure will be called if a custodian is first shut down.
> 
> I'm not sure why we haven't particularly needed this before, except in
> the built-in case of flushing output ports. It's interesting that your
> context is also about flushing.
> 
> At Sun, 04 May 2014 16:19:37 -0400, Tony Garnock-Jones wrote:
> > On 05/04/2014 04:11 PM, Robby Findler wrote:
> > > Sounds to me like you want to wire into the custodian facilities (via
> > > the ffi I believe) but probably starting with just atexit() itself is
> > > okay.
> > 
> > Via the FFI! Gosh. That sounds scary.
> > 
> > I did try register-custodian-shutdown from ffi/unsafe/custodian, but (a)
> > it wasn't called when the program exited normally, and (b) when I called
> > (custodian-shutdown (current-custodian)), it complained about a blocking
> > operation in atomic mode or something like that, and abort()ed. I then
> > explored use of exit-handler instead :-)
> > 
> > Would it make sense to change Racket to ensure the current exit-handler
> > is called at the end of the main program?
> > 
> > Regards,
> >   Tony
> > ____________________
> >   Racket Users list:
> >   http://lists.racket-lang.org/users
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.