Weak pointers and STM

Simon Marlow marlowsd at gmail.com
Mon Dec 8 06:53:01 EST 2008


The way to use finalizers is in conjunction with an exception handler that 
provides an absolute guarantee that the resource will be reclaimed on exit.

Note that Java doesn't guarantee to run finalizers on exit either:

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#runFinalizersOnExit(boolean)

Although in Java it's for different reasons.

We can give more guarantees to C finalizers because they're much simpler:

   - a C finalizer can't synchronise with other Haskell code,
     including Haskell finalizers.
   - we don't have to worry about whether a C finalizer refers to
     other finalizable objects
   - we don't mind if a C finalizer blocks: that's the programmer's problem.

Cheers,
	Simon

Lennart Augustsson wrote:
> From a theoretical perspective I'd say that they are completely
> useless, because there's no guarantee that the finalizer will ever
> run.  You might as well throw them away as use them and there would be
> the same guarantees.
> From a practical perspective they are useful, because they probably
> run.  So you can use them to reclaim most resources.
> 
> I realize that the situation is complicated in ghc, but it also means
> that to get finalizers with guarantees you have to implement them
> yourself rather than relying on the ghc runtime system, which can be
> quite tedious.
> 
>   -- Lennart
> 
> On Mon, Dec 8, 2008 at 9:59 AM, Simon Marlow <marlowsd at gmail.com> wrote:
>> Lennart Augustsson wrote:
>>> Finalizers without guarantees, like what ghc implements, are totally
>>> useless. Since there is no guarantee that the finalizer will ever run
>>> attaching one is a no-op. It has bitten me several times. I wish ghc
>>> implemented finalizers according to the ffi spec.
>> We do plan to do that (I'm sure you're aware of bug #1364), however I'm sure
>> you're also aware that GHC's finalizers are more general than the FFI spec
>> requires in that finalizers can be Haskell computations, and it is this that
>> leads to the lack of guarantees.  Implementing the FFI-style finalizers
>> requires us to treat C finalizers as a special case, rather than
>> implementing them as foreign calls from Haskell finalizers, which is a bit
>> of a pain.
>>
>> I disagree that finalizers are completely useless.  They're just not useful
>> for some of the things you might like them to be useful for, like guaranteed
>> resource reclamation.
>>
>>>   -- Lennart (iPhone)
>> Cheers,
>>        Simon (MS natural keyboard and 28" LCD screen)
>>
>>> On Dec 7, 2008, at 13:12, "Claus Reinke" <claus.reinke at talk21.com> wrote:
>>>
>>>>> Adding finalizers to arbitrary objects was useful for the memo table
>>>>> application we had in mind when weak pointers were introduced, but for all
>>>>> the other applications I've come across since then, we really want to add
>>>>> finalizers to objects whose lifetimes are under programmer control.  Notice
>>>>> how ForeignPtrs attach the finalizer carefully to the MutVar# inside the
>>>>> ForeignPtr, not the ForeignPtr itself.
>>>> One application that was effectively killed by GHC's approach to
>>>> finalizers was GHood (I lost interest when it became apparent that
>>>> GHC was moving away from giving any kinds of guarantees about
>>>> finalizers). The idea was that, just as unsafePerformIO gives us a
>>>> way to instrument the evaluator, so finalizers could have given us a way
>>>> to instrument garbage collection. Then GHood could not only
>>>> have shown when which parts of which structure are first observed
>>>> (how and when structures get unfolded) but also (roughly) when which
>>>> parts of which structure become unreachable (how and when
>>>> structures disappear again). That would have made a very nice tool.
>>>>
>>>> But it would have needed finalizers on arbitrary objects that are
>>>> actually guaranteed to be run, preferably promptly, but not early. Given
>>>> the application, I would have considered wrapping/annotating those objects
>>>> in some transparent way, not visible to the original program, but forcing
>>>> the memory manager to keep track of that object even if that means worse
>>>> code. Only that there are no guarantees whatsoever on these finalizers
>>>> anymore (there were some back then, but it emerged that they weren't backed
>>>> up by the implementation).
>>>> Which also hurts other, table-like, applications: I have an application
>>>> where I need to keep track of synchronous communication channels, basically:
>>>> advance each live channel at every step. Now, I would like to attach
>>>> finalizers to the channels, so that when there are no more threads having
>>>> references to a channel, the channel gets removed
>>>> from the tracking table. But without finalizer guarantees, there is no
>>>> guarantee that the table will not simply keep accumulating more and
>>>> more of those dynamically created channels..
>>>>
>>>> I, for one, would like to have good support for "adding finalizers to
>>>> arbitrary objects with useful run guarantees". Actually, it is a bit hard
>>>> to understand what finalizers without any guarantees (System.Mem.Weak)
>>>> are supposed to achieve?
>>>>
>>>> Claus
>>>>
>>>> _______________________________________________
>>>> Glasgow-haskell-users mailing list
>>>> Glasgow-haskell-users at haskell.org
>>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>



More information about the Glasgow-haskell-users mailing list