[Haskell-cafe] Re: Are handles garbage-collected?

oleg at pobox.com oleg at pobox.com
Mon Oct 25 22:50:30 EDT 2004

Simon Marlow wrote:
> I've been wondering whether having a more synchronous kind of
> finalizer would be a good thing.

Hans Boehm in his POPL2003 paper "Destructors, Finalizers, and
Synchronization" persuasively argued that finalizers _must_ be
asynchronous. That assertion is the title of Section 3.5 of the paper.

Peter Simons wrote:

> input -> iodriver --> connection handler --+
>            | /|\                            |
>  output <--+  +-----------------------------+
>                        (Event, State)
> ...
> The I/O driver is a StateT monad which calls the (various)
> connection handlers every time new input is available from
> the network. The handlers are StateT monads, too, and their
> respective state is stored in the I/O driver's state when
> they return.
> ...
> The only solution I would know is to put the entire state of
> the connection handler into an MVar, so that any changes to
> it are immediate for the I/O driver. But that approach feels
> like overkill to me.

It seems you don't need to store the whole state in MVar: it's enough
to store a `clean-up' action. Suppose there exists an MVar known to
both a connection handler and the iodriver. The type of MVar's value
is Maybe (IO ()). When the connection handler opens a Handle, it
places a Just action that will close the handle. If the connection
handler makes it to the end without getting an exception, it, right
before returning to the iodriver, replaces that cleanup action with
Nothing. The iodriver, upon getting control back, checks the MVar and
executes whatever action is outstanding. The action can refer to any
context it needs for the clean-up.

Come to think of it, perhaps MVar is overkill. From your description,
it seems that each connection handle has its own private piece of
state inside the iodriver state. Perhaps it is not so much to ask to
add an IORef (Maybe (IO ())) to that state. The iodriver will check
that IORef upon getting control back from the control handler; Or the
driver can scan all these IORefs upon receiving an event, an
exception, etc.

Perhaps a more general approach is a special Handle leasing
component. Can we assume that a connection handler has a specific ID?
Can we assume that all alive connection handlers can be enumerated (it
seems so from the above description: iodriver is aware of all alive
connection handlers). If these assumptions hold, we can introduce one
level of indirection. Whenever a connection handler needs a Handle, it
applies to the Lord of Handles (LoH), passing its own id and the file
name. The LoH gives an id of a handle (or the handle itself). The LoH
also stores the allocated Handle and the component ID in its
tables. From time to time (or on certain events) the LoH checks all
the open handles to see if the corresponding connection handlers are
still alive.

More information about the Haskell-Cafe mailing list