
Brad Clow:
So does GHC implement some sychronisation given that a mutation is occuring under the covers, ie. the thunk is being replaced by the result?
I believe so, but I have no idea of the details.
I am using a TVar to build results of forked functions in. I had a quick go at changing to channels so I could use Dons library but kept getting blocking exceptions, so I have left it as is for the moment.
Don's library is fairly simple. It adds a strictness annotation to force each value you write to a MVar or Chan, so for example, (Control.Concurrent.MVar.Strict.putMVar v x) is basically equivalent to (Control.Concurrent.MVar.putMVar v $! x). This is useful for returning results from worker threads, because it makes it more likely that the worker thread actually does the work. I say, "more likely", because the strictness annotation only forces the value to WHNF. If you have a deep structure, you might need a more sophisticated forcing function. Since you're using STM, Don's library doesn't (yet) help you, though that ought to be easy to fix. In the meantime, you can at least apply the essential idea, which means using (writeTVar v $! x) instead of (writeTVar v x) when returning results from a worker thread.