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;