[MLton] adding synchronous finalizers

Stephen Weeks MLton@mlton.org
Fri, 1 Oct 2004 12:26:40 -0700


> My point was that one might have multiple threads and still not want
> signals to be handled automatically.  I.e., to handle them only
> during some kind of poll call.  The same is the case for finalizers.

I agree.

> I really don't know what the right solution is.
> My notion was (when I wrote the last mail) to have a signle poll function
> and then a flag which takes one of the following values:
> 1. Nothing is done automatically, poll checks for signals and finalizers.
> 2. Both signals and finalizers are done automatically (poll does nothing).
> 3. Signals are automatic but finalizers are not, poll only checks finalizers.
> 4. Finalizers are automatic but signals are not, poll only checks signals.
> 
> I don't really like this.

I agree it's messy.  I'm tempted to add just the finalizer case, since
I think I understand it.  See the code below for what I have in mind.
As you can see, it can be added without any support from us, which
argues that we should leave it out.  But I think it's the kind of
thing that programmers are likely to get wrong (and perhaps I did),
especially in an otherwise single-threaded program.  So, it seems to
me like it belongs in MLton.Finalizable.

----------------------------------------------------------------------

structure Finalizable:
   sig
      include MLTON_FINALIZABLE

      val finalizeSynchronously: bool ref
      val runFinalizers: unit -> unit
   end =
   struct
      structure F = MLton.Finalizable

      open F
	 
      val finalizeSynchronously: bool ref = ref false
	 
      val finalizers: (unit -> unit) list ref = ref []
	 
      fun addFinalizer (v, f) =
	 F.addFinalizer
	 (v, 
	  if !finalizeSynchronously
	     then (fn a => finalizers := (fn () => f a) :: !finalizers)
	  else f)
	    
      fun runFinalizers () =
	 List.app (fn f => f ())
	 (MLton.Thread.atomically
	  (fn () => !finalizers before (finalizers := [])))
   end