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

Reply via email to