Thanks for the example - it was a useful to see how to use the Thread structure. And to see how easy it was. That's a nice library.

Attached is a first stab at implementing the FINALIZABLE signature shown below, which is identical to MLTON_FINALIZABLE. The code is based on the MLton implementation but with a number of differences. As mentioned in the other email, there seems to be an issue with finalizers not being run when exiting via OS.Process.exit.

Phil


signature FINALIZABLE =
  sig
    type 'a t
    val new : 'a -> 'a t
    val addFinalizer : 'a t * ('a -> unit) -> unit
    val finalizeBefore : 'a t * 'b t -> unit
    val touch : 'a t -> unit
    val withValue : 'a t * ('a -> 'b) -> 'b
  end


16/09/15 11:56, David Matthews wrote:
On 15/09/2015 23:06, Phil Clayton wrote:
In MLton, creating a finalizable value from the pointer and size is
simple.  Roughly as follows:

   fun fromNewPtr p n =
     let
       val array = Finalizable.new p
     in
       Finalizable.addFinalizer (t, fn p => free_ (p, n));
       array
     end

where free_ is the C free function.  If Poly/ML can use the same or
similar code, that would be much easier!

This is my quick attempt to create something similar.  As long as the
result of the call to makeFinal is reachable the finalisation function
will not be called.  Once it becomes unreachable the finalisation
function will be called soon after the GC.  I've only tested it with
explicit calls to PolyML.fullGC but it should work equally when the GC
is activated automatically.  However it does require a full GC and that
can occur relatively infrequently.
David

local
     open Weak
     val finals = ref []

     fun threadFn () =
     let
         val () = Thread.Mutex.lock weakLock
         fun doFilter (ref (SOME _), _) = true
         |   doFilter (ref NONE, f) = (f(); false)
     in
         while true do
         (
             finals := List.filter doFilter (!finals);
             Thread.ConditionVar.wait(weakSignal, weakLock)
         )
     end

     val _ = Thread.Thread.fork(threadFn, [])
in
     fun makeFinal (f : unit -> unit) =
     let
         val r = ref ()
         val () =
             ThreadLib.protect weakLock
                 (fn () => finals := (weak(SOME r), f) :: ! finals) ()
     in
         r
     end
end;
_______________________________________________
polyml mailing list
[email protected]
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml



Attachment: finalizable-1.sml.gz
Description: GNU Zip compressed data

_______________________________________________
polyml mailing list
[email protected]
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

Reply via email to