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

2014-08-17 Thread Neil Toronto
That would be really nice for data structures defined in TR and used in 
untyped Racket, for which the contract boundary imposes O(n) overhead 
for everything. Also, it sounds dangerous. :D


It wouldn't solve the problem entirely, though. Here's an untyped 
program that has it:


#lang racket

(module resource racket
  (require (only-in ffi/unsafe register-finalizer))

  (provide
   (contract-out
[connect-os-resource  (-> (struct/c os-resource-wrapper real?)
  void?)])
   get-os-resource
   (struct-out os-resource-wrapper))

  (struct os-resource-wrapper (x) #:mutable)

  (define os-resource 0)
  (define (get-os-resource) os-resource)

  (define (connect-os-resource w)
(set! os-resource (add1 os-resource))
(printf "impersonator? ~v  chaperone? ~v~n"
(impersonator? w)
(chaperone? w))
(register-finalizer
 w (λ (w) (set! os-resource (sub1 os-resource))

(require (submod "." resource))

(define w (os-resource-wrapper 1))
(connect-os-resource w)

(printf "os-resource = ~v~n" (get-os-resource))
(collect-garbage)
(sleep 1)  ; give finalizers a chance to run
(printf "os-resource = ~v~n" (get-os-resource))


This was actually hard to come up with. We usually use flat contracts 
like `os-resource-wrapper?`, and count on struct contracts at the 
boundary to ensure that `os-resource-wrapper?` implies (struct/c 
os-resource-wrapper real?) for any value coming in. When I did that, 
there was no way to provoke the error: `connect-os-resource` registered 
a finalizer on an unwrapped value, or on a wrapped value *for which the 
external module didn't have access to the original*.


The above program still exhibits the wrong-value-finalizer problem if 
the struct is provided with a contract. It probably gets wrapped twice 
in that case: once when created in the external module, and once on the 
way into `connect-os-resource`.


So I think our contracting habits make the problem rare, but it's still 
possible with just the contract system. I'm going to submit a bug report.


Neil ⊥

On 08/17/2014 05:19 PM, Matthias Felleisen wrote:


I imagine a type-definition construct that allows programmers to specify how 
the type is translated into a contract. Think (define-trusted-type Finalizer C) 
and then the C specifies how little and how much of the type you wish to check.

And yes, this is potentially a soundness hole but I am thinking that the 
primary uses could be connected to things in the core or the FFI. And 
programmers who wish to reduce the soundness of TR could use it to speed up 
boundary crossings at the cost of getting things wrong. In a sense, it's an FFI 
for types.

-- Matthias







On Aug 17, 2014, at 3:47 PM, Sam Tobin-Hochstadt wrote:


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
 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
 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 Open

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

2014-08-17 Thread Matthias Felleisen

I imagine a type-definition construct that allows programmers to specify how 
the type is translated into a contract. Think (define-trusted-type Finalizer C) 
and then the C specifies how little and how much of the type you wish to check. 

And yes, this is potentially a soundness hole but I am thinking that the 
primary uses could be connected to things in the core or the FFI. And 
programmers who wish to reduce the soundness of TR could use it to speed up 
boundary crossings at the cost of getting things wrong. In a sense, it's an FFI 
for types. 

-- Matthias







On Aug 17, 2014, at 3:47 PM, Sam Tobin-Hochstadt wrote:

> 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
>  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
>>>  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
>> 


_
  Racket Developers list:
  http://lists.racket-lang.org/dev


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

2014-08-17 Thread Sam Tobin-Hochstadt
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
 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
>>  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
>

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


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

2014-08-17 Thread Matthias Felleisen

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
>  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


_
  Racket Developers list:
  http://lists.racket-lang.org/dev


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

2014-08-17 Thread Sam Tobin-Hochstadt
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
 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

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


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

2014-08-17 Thread Matthias Felleisen

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


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

2014-08-16 Thread Neil Toronto
That's what I think. The more contracted our values get in Racket 
programs, the less we can trust `register-finalizer` if it doesn't change.


Currently, `register-finalizer` tends to be used right after allocation, 
when objects don't usually have contracts yet. It doesn't have to be, 
though.


Neil ⊥

On 08/16/2014 10:46 AM, Sam Tobin-Hochstadt wrote:

That's clearly the right solution for this particular bug, but it does
seem like there's a more general problem here.

Sam

On Sat, Aug 16, 2014 at 10:40 AM, Robby Findler
 wrote:

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  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



_
 Racket Developers list:
 http://lists.racket-lang.org/dev


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

2014-08-16 Thread Sam Tobin-Hochstadt
That's clearly the right solution for this particular bug, but it does
seem like there's a more general problem here.

Sam

On Sat, Aug 16, 2014 at 10:40 AM, Robby Findler
 wrote:
> 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  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
>

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


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

2014-08-16 Thread Robby Findler
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  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


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

2014-08-16 Thread Neil Toronto
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