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

From: Sam Tobin-Hochstadt (samth at cs.indiana.edu)
Date: Sun Aug 17 15:47:36 EDT 2014

Can you say more about what the API for what you're imagining is?

Sam

On Sun, Aug 17, 2014 at 3:41 PM, Matthias Felleisen
<matthias at ccs.neu.edu> wrote:
>
> I am imagining that the type compilation of type Finalizer and such things would be parameterized over programmer code which would yield a 'trusted' 'thing' in this case except that this would open the door for other such things.
>
>
>
>
> On Aug 17, 2014, at 3:39 PM, Sam Tobin-Hochstadt wrote:
>
>> How would that change things here? The issue is about
>> finalizer-for-what, and that chaperones/impersonators affect object
>> identity.
>>
>> Sam
>>
>> On Sun, Aug 17, 2014 at 3:37 PM, Matthias Felleisen
>> <matthias at ccs.neu.edu> wrote:
>>>
>>> Could we benefit from an abstract/opaque Finalizer type here? I know we don't have those yet but it may address the general problem. -- Matthias
>>>
>>>
>>>
>>>
>>> On Aug 16, 2014, at 8:55 AM, Neil Toronto 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
>>>
>>>
>>> _________________________
>>>  Racket Developers list:
>>>  http://lists.racket-lang.org/dev
>


Posted on the dev mailing list.