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

