<HTML><BODY>Ready. Package `finalizer' on pkgs.racket-lang.org<br><br><br>Sat, 02 Aug 2014 21:12:50 +0400 от Roman Klochkov <kalimehtar@mail.ru>:<br>
<blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">
        <div id="">
        



    









        
        


        
        
        
        
        

        
        

        
        



<div class="js-helper js-readmsg-msg">
        <style type="text/css"></style>
        <div>
                <base target="_self" href="https://e.mail.ru/">
                
                        <div id="style_14070000930000000911_BODY">
Here we have a thread per every module, that use such approach. It is better,than a thread per object, but ...<br>How many such threads can Racket run without performance degrading?<br><br>Maybe better make common module for such purpose? Hmm..., I think I should make one...<br><br><br>Sat, 2 Aug 2014 07:38:08 -0500 от Robby Findler <robby@eecs.northwestern.edu>:<br>
<blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px;">
        <div>
        



    









        
        


        
        
        
        
        

        
        

        
        



<div>
        
        <div>
                
                
                        <div>Probably you want to do something like this, I guess. It creates a<br>
single thread that just waits until anything registered with<br>
an-executor is garbage and then runs the executors. They will run<br>
asynchronously, but perhaps that's okay for your usecase.<br>
<br>
Robby<br>
<br>
#lang racket<br>
(define an-executor (make-will-executor))<br>
(void<br>
 (thread<br>
  (λ ()<br>
    (let loop ()<br>
      (will-execute an-executor)<br>
      (loop)))))<br>
<br>
(define a-box (box #f))<br>
(will-register an-executor<br>
               a-box<br>
               (λ (x) (printf "a-box is now garbage\n")))<br>
(collect-garbage) (collect-garbage) (collect-garbage)<br>
(printf "breaking the link\n")<br>
(set! a-box #f)<br>
(collect-garbage) (collect-garbage) (collect-garbage)<br>
<br>
On Sat, Aug 2, 2014 at 7:31 AM, Roman Klochkov <<a target="_blank">kalimehtar@mail.ru</a>> wrote:<br>
> So I can write<br>
><br>
> (define (make-obj stream)<br>
>    (define res  (obj (open-output-file "out.dat")))<br>
>    (define will (make-will-executor))<br>
>    (will-register will res (lambda (x) (close-output-port (obj-file x))))<br>
>    (thread (lambda () (let loop () (will-try-execute will) (sleep 1)<br>
> (loop)))))<br>
><br>
> to make my objects? Additional threads don't hinder performance, do they?<br>
><br>
> Or should I somehow figure out if the thread is already running, don't run<br>
> it and use common `will' for all objects?<br>
><br>
> Sat, 2 Aug 2014 07:00:04 -0500 от Robby Findler<br>
> <<a target="_blank">robby@eecs.northwestern.edu</a>>:<br>
><br>
> One way is to set up a separate thread to do that.<br>
><br>
> The reason they are not called automatically is sometimes running the<br>
> procedure passed to will-register needs to access some shared state<br>
> and so your program must be allowed to be in control of the timing of<br>
> the executor.<br>
><br>
> In this case, it sounds like you can run the executor at any time, so<br>
> just creating a thread to close the port inside my-obj should work<br>
> fine.<br>
><br>
> Robby<br>
><br>
><br>
> On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov <<a target="_blank">kalimehtar@mail.ru</a>> wrote:<br>
>> Then how?<br>
>><br>
>> Suppose I have<br>
>> (struct obj (file))<br>
>> (define my-obj (obj (open-output-file "out.dat")))<br>
>><br>
>> What I have to write to close the file, when my-obj will be GC'ed?<br>
>><br>
>> I can write<br>
>> (define will (make-will-executor))<br>
>> (will-register will my-obj (lambda (x) (close-output-port (obj-file x))))<br>
>><br>
>> But as far as I understand, it will not be called until `will-execute' or<br>
>> `will-try-execute' will be manually called?<br>
>><br>
>> Then how to call will-try-execute when GC is collecting my-obj?<br>
>><br>
>><br>
>> Sat, 2 Aug 2014 11:57:32 +0100 от Matthew Flatt <<a target="_blank">mflatt@cs.utah.edu</a>>:<br>
>><br>
>> No, use the safe "will executors" API, instead.<br>
>><br>
>> The unsafe finalizer API is for low-level, atomic finalization. Closing a<br>
>> port can flush buffers and more, and it's not a good idea to do that in an<br>
>> unsafe atomic context.<br>
>><br>
>>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov <<a target="_blank">kalimehtar@mail.ru</a>> wrote:<br>
>>><br>
>>> I have a structure, that has a filestream inside it. File have to be<br>
>>> cosed, when the structure is not used anymore (so gargbage collected).<br>
>>><br>
>>> Is the best way to do<br>
>>> (require ffi/unsafe)<br>
>>> (register-finalizer my-obj<br>
>>> (lambda (x) (close-output-port (obj-file x))))<br>
>>><br>
>>> ?<br>
>>><br>
>>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my<br>
>>> program actually doesn't use FFI?<br>
>>><br>
>>><br>
>>> --<br>
>>> Roman Klochkov<br>
>>> ____________________<br>
>>> Racket Users list:<br>
>>> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
>><br>
>><br>
>><br>
>> --<br>
>> Roman Klochkov<br>
>><br>
>> ____________________<br>
>> Racket Users list:<br>
>> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
>><br>
><br>
><br>
><br>
> --<br>
> Roman Klochkov<br>
</div>
                        
                
                
        </div>

        
</div>


</div>
</blockquote>
<br>
<br>-- <br>Roman Klochkov<br>

</div>
                        <div>____________________<br>
  Racket Users list:<br>
  <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br>
</div>
                
                <base target="_self" href="https://e.mail.ru/">
        </div>

        
</div>


</div>
</blockquote>
<br>
<br>-- <br>Roman Klochkov<br></BODY></HTML>