
On Wednesday 30 October 2002 01:20 am, Simon Marlow wrote:
Not unless the putMVar blocks. The proof that it never blocks depends on the behaviour of other threads though: if you have another thread doing putMVar on the same MVar, then it may block. Other threads must be "well-behaved" for it to work.
At first glance, this seems like an untenable situation, but it's not really. The mechanisms provided in GHC are quite low-level. Careful design of higher-level combinators (implemented in terms of block/unblock, etc.) appropriate to the problem at hand is essential. If all of threads use the high-level combinators, you can guarantee that they're all well-behaved. A common idiom is the "with<Resource>" style of combinator. Here's withSocket, which guarantees that the socket will be closed at the end of the withSocket, even if the thread using it is killed: withSocket :: Socket -> (Socket -> IO a) -> IO a withSocket sock ioa = finally (ioa sock) (sClose sock) A similar idea works for shared resources; see Control.Concurrent.MVar.withMVar for the classic example. It changes the way your code looks pretty dramatically, but it makes the job of debugging multi-threaded, multi-process programs much easier. Cheers, Andy -- Andy Moran Galois Connections Inc. Fax. (503) 350 0833 3875 SW Hall Blvd. http://www.galois.com Beaverton, OR 97005 moran@galois.com