MVar interface [was: Re: ForeignPtr-related signatures]

Dean Herington heringto at
Mon Nov 18 11:43:00 EST 2002

Simon Marlow wrote:

> > Simon Marlow wrote:
> > > [...] There was this, from Dean Herrington:
> > >
> > >
> > >
> > > I don't have any strong feelings (I rarely do, where names are
> > > concerned).
> >
> > I would be happy with his proposal. We can leave the IORef
> > stuff in IOExts
> > as it is and use the new signatures and functions in
> > Data.IORef. The only
> > annoying thing is the signature of Data.IORef.modifyIORef,
> > but we could
> > declare the old signature as a bug...  :-]
> Actually, looking at the proposal again, I don't think I like the
> changes to the MVar interface.  atomicModifyMVar seems strange, because
> modifyMVar is already atomic.  We have to be careful about trying to
> smooth over differences between IORef and MVar where those differences
> are real and important.

The current `modifyMVar`, though "exception safe", is not "atomic" in the
same way that the proposed `atomicModifyMVar` would be.  Unless I
misunderstand, during the execution of `modifyMVar`'s second argument, the
mvar is empty and could be filled by some other thread.  With
`atomicModifyMVar`, the contents of the mvar are changed atomically, based
on the given (pure) function; no other thread can intervene.

The difference described above is noticeable in the implementation of
`readMVar` and `swapMVar`.  As currently implemented, these functions are
not atomic as one might expect.  They would better be implemented in terms
of `atomicModifyMVar`.

Thinking about `readMVar` and `swapMVar` reminds me that `tryReadMVar` and
`trySwapMVar` are missing from the interface.

Thinking about the "try" and "atomic" variants suggests that we ought also
to add:

    atomicTryModifyMVar :: MVar a -> (a -> (a, b)) -> IO (Maybe b)
    atomicTryModifyMVar_ :: MVar a -> (a -> a) -> IO Bool

with semantics that I think are obvious.

> I don't mind changing modifyIORef to have a signature which is more
> similar to modifyMVar, and I think adding atomicModifyIORef_ is a good
> idea (although it needs a new primitive if we're to take advantage of
> its efficiency over atomicModifyIORef).  Summary:
>  - make modifyIORef's type match modifyMVar
>  - add modifyIORef_
>  - add atomicModifyIORef and atomicModifyIORef_

One might reasonably worry about the proliferation of MVar manipulation
functions.  I think it's useful to realize that there are semantically only
four primitives in the proposed extended interface: `newEmptyMVar`,
`atomicModifyMVar`, `atomicTryModifyMVar`, and `addMVarFinalizer`.  All the
other functions can be built simply out of these primitives.  In fact, I
would recommend we include in the documentation for all the nonprimitive
functions their definitions in terms of the primitives.

 -- Dean

More information about the FFI mailing list