[MLton-user] Feature request: MLton.Finalizable

Matthew Fluet fluet at tti-c.org
Mon Jun 2 17:05:58 PDT 2008


On Mon, 2 Jun 2008, John Reppy wrote:
> I'm using finalization as a backstop for explicit management
> of resources (e.g., textures and shaders).  I typically use the type
>
> 	Int32.int option ref MLton.Finalizable.t
>
> to represent these resources and set the ref to NONE when it
> has been explicitly deallocated.

Any reason not to simply let finalization take care of deallocation?  I 
guess if you have limited resources, you might want to proactively 
release them.

> I could streamline this
> process with the addition of the following two operations to
> the Finalizable structure:
>
>       (* remove all finalization functions from the object *)
> 	 val cancelFinalizers : 'a t -> unit
>
>       (* change the state of the finalized object *)
> 	 val update ('a t * 'a) -> unit

Why would you need both?

If you can remove the finalization functions, then you won't need to 
change the state of the resource, since at an explicit deallocation you 
will first cancel the finalization functions and then really delete:

   type res = Int32.int MLton.Finalizable.t

   fun delete res =
       (MLton.Finalizable.cancelFinalizers res
        ; MLton.Finalizable.withValue (res, fn r => reallyDelete r))

If you can update the state of the finalized object, then you won't need 
to delete the finalization functions, since at an explicit deallocation 
you will really delete the resource and then change its state:

   type res = Int32.int option MLton.Finalizable.t

   fun delete res =
       (MLton.Finalizable.withValue (res, fn SOME r => reallyDelete r
                                           | NONE => raise Fail "Resource gone")
        ; MLton.Finalizable.update (res, NONE))

> The implementation is straightforward:
>
> 	fun cancelFinalizers (T{finalizers, ...}) = finalizers := []
>
> 	fun update (T{value, ...}, x) = value := x
>
> Any chance of getting these added to MLton?

Your 'update' function doesn't work with the Finalizable implementation. 
The finalization functions are invoked on the original value v used to 
construct the finalizable value.  The closure passed off to the GC handler 
can't be closed over the reference cell pointed to by the weak pointer, 
else the reference cell would always be live.

You can do it with another level of indirection, but in that case you 
might as well leave it to the client.




More information about the MLton-user mailing list