content: -- | Lifted concurrency operators and a some useful concurrency abstractions
  module GF.Infra.Concurrency(
      module GF.Infra.Concurrency,
      C.forkIO,
      C.MVar,C.modifyMVar,C.modifyMVar_,
      C.Chan
   ) where
  import qualified Control.Concurrent as C
  import System.IO.Unsafe(unsafeInterleaveIO)
  import Control.Monad((<=<))
  import Control.Monad.Trans(MonadIO(..))
  
  -- * Futures
  
  newtype Future a = Future {now::IO a}
  
  spawn io = do v <- newEmptyMVar
                C.forkIO $ putMVar v =<< io
                return (Future (readMVar v))
  
  parMapM f = mapM now <=< mapM (spawn . f)
  
  -- * Single-threaded logging
  
  newLog put =
    do logchan <- newChan
       liftIO $ C.forkIO (mapM_ put =<< getChanContents logchan)
       return (writeChan logchan)
  
  -- * Lifted concurrency operators
  
  newMVar x = liftIO $ C.newMVar x
  readMVar v = liftIO $ C.readMVar v
  putMVar v = liftIO . C.putMVar v
  
  newEmptyMVar :: MonadIO io => io (C.MVar a)
  newEmptyMVar = liftIO C.newEmptyMVar
  
  newChan :: MonadIO io => io (C.Chan a)
  newChan = liftIO C.newChan
  
  getChanContents ch = liftIO $ C.getChanContents ch
  writeChan ch = liftIO . C.writeChan ch
  
  
  -- * Delayed IO
  
  lazyIO = unsafeInterleaveIO
  