Thread blocked indefinitely in an MVar operation

Three days later and its solved: Was actually unrelated to either the networking or concurrency code, and infact caused by my incorrect re-implementation of Yampas dpSwitch in Netwire. Corrected code posted below for anyone wishing to implement this function:

dpSwitch :: (Monoid e, Applicative m, Monad m, T.Traversable col) => (forall wire. a -> col wire -> col (b, wire))
     -> col (Wire s e m b c)
     -> Wire s e m (a, col c) (Event d)
     -> (col (Wire s e m b c) -> d -> Wire s e m a (col c))
     -> Wire s e m a (col c)
dpSwitch route wireCol switchEvtGen continuation = WGen $ gen wireCol switchEvtGen
where
    gen wires switchEvtGenWire _ (Left x) = return (Left mempty, WGen $ gen wires switchEvtGenWire)
    gen wires switchEvtGenWire ws (Right x) = do            
        let routings = route x wires
        wireSteps <- T.sequenceA (fmap (\(wireInput, wire) -> stepWire wire ws (Right wireInput)) routings)
        let wireOutputs = T.sequenceA (fmap fst wireSteps)
            steppedWires = fmap snd wireSteps
        case wireOutputs of
            Left wireInhibitedOutput -> return (Left wireInhibitedOutput, WGen $ gen steppedWires switchEvtGenWire)
            Right wireResultOutput -> do
                (event, steppedSwitchEvtGenWire) <- stepWire switchEvtGenWire ws (Right (x, wireResultOutput))
                case event of
                    Left eventInhibited -> return (Left eventInhibited, WGen $ gen steppedWires steppedSwitchEvtGenWire)
                    Right NoEvent -> return (wireOutputs, WGen $ gen steppedWires steppedSwitchEvtGenWire)
                    Right (Event e) -> return (wireOutputs, continuation steppedWires e)

For anyone who might stumble on this, some additional information thread blocked indefinitely in an MVar operation is not really that smart. It happens when every thread that contains a reference to the MVar is trying to read (or write) to that location, has died, or is waiting on another primitive that is blocked forever. eg thread 1 is trying to read MVar a and waiting on thread 2 which is either dead, also trying to read MVar a, or trying to read MVar b which can only be written to in thread 1.

The following code happily hangs forever:

do
  a <- newEmptyMVar
  forkIO (readMVar a >>= print)
  putMVar a $ last $ repeat 0

I think I see the problem -- it is in Server.hs. You have operations that do network IO inside a withMVar call. Now imagine that IO blocks effectively forever. You neither get an exception that forces the var to be replaced, nor does the operation complete normally and replace the var, and hence you get stuck.

In general, you should not do any significant operations in a withMVar call, even though you can. And if you do any such operations, you need to be double-sure that you effectively guard them with timeouts, etc. such that you are sure they always complete one way or another.