[racket-dev] Should `register-finalizer` unwrap impersonators?

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Sat Aug 16 10:40:13 EDT 2014

Seems simplest to be to have typed racket know to trust register finalizer
and thus avoid wrapping it with a contract.

Robby

On Saturday, August 16, 2014, Neil Toronto <neil.toronto at gmail.com> wrote:

> Short version: the contract system doesn't allow `register-finalizer` to
> be used in Typed Racket.
>
> Long version: consider the following Typed Racket program, in which
> instances of `os-resource-wrapper` represent an operating system resource
> `os-resource`, which itself is just a counter. It attempts to register a
> finalizer for allocated wrappers, which decrements the counter.
>
>
> #lang typed/racket
>
> (require/typed
>  ffi/unsafe
>  [register-finalizer  (All (A) (-> A (-> A Any) Void))])
>
> (: os-resource Integer)
> (define os-resource 0)
>
> (struct os-resource-wrapper ())
>
> (: alloc-os-resource (-> os-resource-wrapper))
> (define (alloc-os-resource)
>   (set! os-resource (add1 os-resource))
>   (define w (os-resource-wrapper))
>   (register-finalizer w (λ (w) (set! os-resource (sub1 os-resource))))
>   w)
>
> (define w (alloc-os-resource))
> (printf "os-resource = ~v~n" os-resource)
> (collect-garbage)
> (sleep 1)  ; give finalizers a chance to run
> (printf "os-resource = ~v~n" os-resource)
>
>
> I get this output:
>
>   os-resource = 1
>   os-resource = 0
>
> The finalizer is being run while the program still has a pointer to the
> wrapper object. I think it's because the wrapper object is being
> impersonated when it's sent across the contract barrier, and the
> *impersonator* is getting the finalizer. (Or it's a chaperone, or an
> impostor, or a charlatan, or whatever. Let's go with impersonator.)
>
> In my specific case, the OS resources are OpenGL objects; e.g. vertex
> object arrays. The call to `register-finalizer` *must* be in Typed Racket
> code because the wrapper contains an (Instance GL-Context<%>), which can't
> have a contract put on it, so it can't pass from untyped to typed code.
>
> Is there any reason for `register-finalizer` to behave this way? Does it
> ever make sense to register a finalizer on an impersonator?
>
> Neil ⊥
> _________________________
>  Racket Developers list:
>  http://lists.racket-lang.org/dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20140816/6b05772c/attachment.html>

Posted on the dev mailing list.