[racket] atexit_closer in an extension

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Tue Jun 29 11:38:14 EDT 2010

At Tue, 29 Jun 2010 16:23:33 +0100, Norman Gray wrote:
> I have a script
> #lang racket
> (require "src/build/librdf-extn.rkt") ; wraps the librdf library
> (printf "Hello~%")
> Nothing exotic there.  However:
> % racket --require try.rkt                       
> Hello
> % racket --require try.rkt >try.out; cat try.out
> % 
> That is, stdout appears to get eaten when it's redirected to a file.

The difference is that the port is not auto-flushed on newlines in the
second case. Normally, it would be flushed on exit.

>     scheme_add_atexit_closer(mzrdf_exit_closer);
> [...]
> void mzrdf_exit_closer(Scheme_Object* o, Scheme_Close_Custodian_Client* f, 
> void* d) 
> {
>     if (f != NULL)
>         f(o, d);
> }

Your closer should probably only handle specific kinds of objects. In
this case, it is shutting down the stdout port, which forces the port
closed without flushing. That overrides the action of a
previously-installed atexit closer (which will run later) that flushes
open output ports.

> It's almost as if I'm stomping on some other atexit closer, 

Exactly, though that would be difficult to infer from the docs. I'll
improve them.

To be clear, you're not completely replacing an existing atexit closer,
but running earlier than the existing one.

Posted on the users mailing list.