packages feed

stm-conduit 0.2.1 → 0.2.2

raw patch · 2 files changed

+70/−22 lines, 2 files

Files

Data/Conduit/TMChan.hs view
@@ -1,62 +1,110 @@--- | Contains a simple source and sink for linking together conduits in+-- | * Introduction+--+--   Contains a simple source and sink for linking together conduits in --   in different threads. Usage is so easy, it's best explained with an --   example: -- --   We first create a channel for communication... -----   > do chan <- atomically $ newTMChan+--   > do chan <- atomically $ newTBMChan 16 -- --   Then we fork a new thread loading a wackton of pictures into memory. The --   data (pictures, in this case) will be streamed down the channel to whatever --   is on the other side. -----   >    _ <- forkIO . runResourceT $ loadTextures lotsOfPictures $$ sinkTMChan chan+--   >    _ <- forkIO . runResourceT $ loadTextures lotsOfPictures $$ sinkTBMChan chan -- --   Finally, we connect something to the other end of the channel. In this --   case, we connect a sink which uploads the textures one by one to the --   graphics card. -----   >    runResourceT $ sourceTMChan chan $$ Conduit.mapM_ (liftIO . uploadToGraphicsCard)+--   >    runResourceT $ sourceTBMChan chan $$ Conduit.mapM_ (liftIO . uploadToGraphicsCard) -- --   By running the two tasks in parallel, we no longer have to wait for one --   texture to upload to the graphics card before reading the next one from --   disk. This avoids the common switching of bottlenecks (such as between the --   disk and graphics memory) that most loading processes seem to love. -----   Control.Concurrent.STM.TMChan is re-exported for convenience.-module Data.Conduit.TMChan ( module Control.Concurrent.STM.TMChan+--   Control.Concurrent.STM.TMChan and Control.Concurrent.STM.TBMChan are+--   re-exported for convenience.+--+--   * Caveats+--+--   It is recommended to use TBMChan as much as possible, and generally avoid+--   TMChan usage. TMChans are unbounded, and if used, the conduit pipeline+--   will no longer use a bounded amount of space. They will essentially leak+--   memory if the writer is faster than the reader.+--+--   Therefore, use bounded channels as much as possible, preferably with a+--   high bound so it will be hit infrequently.+module Data.Conduit.TMChan ( module Control.Concurrent.STM.TBMChan+                           , sourceTBMChan+                           , sinkTBMChan+                           , module Control.Concurrent.STM.TMChan                            , sourceTMChan                            , sinkTMChan                            ) where  import Control.Monad.IO.Class ( liftIO )-import Control.Concurrent.STM ( atomically )+import Control.Concurrent.STM+import Control.Concurrent.STM.TBMChan import Control.Concurrent.STM.TMChan  import Data.Conduit +chanSource :: chan -- ^ The channel.+           -> (chan -> STM (Maybe a)) -- ^ The 'read' function.+           -> (chan -> STM ()) -- ^ The 'close' function.+           -> Source IO a+chanSource ch reader closer = src+    where+        src = Source pull close+        pull = do a <- liftIO . atomically $ reader ch+                  case a of+                    Just x  -> return $ Open src x+                    Nothing -> return Closed+        close = liftIO . atomically $ closer ch+{-# INLINE chanSource #-}++chanSink :: chan -- ^ The channel.+         -> (chan -> a -> STM ()) -- ^ The 'write' function.+         -> (chan -> STM ()) -- ^ The 'close' function.+         -> Sink a IO ()+chanSink ch writer closer = sink+    where+        sink = SinkData push close+        push input = do liftIO . atomically $ writer ch input+                        return $ Processing push close+        close = liftIO . atomically $ closer ch+{-# INLINE chanSink #-}++-- | A simple wrapper around a TBMChan. As data is pushed into the channel, the+--   source will read it and pass it down the conduit pipeline. When the+--   channel is closed, the source will close also.+--+--   If the channel fills up, the pipeline will stall until values are read.+sourceTBMChan :: TBMChan a -> Source IO a+sourceTBMChan ch = chanSource ch readTBMChan closeTBMChan+{-# INLINE sourceTBMChan #-}+ -- | A simple wrapper around a TMChan. As data is pushed into the channel, the --   source will read it and pass it down the conduit pipeline. When the --   channel is closed, the source will close also. sourceTMChan :: TMChan a -> Source IO a-sourceTMChan ch = src-    where-        src = Source pull close-        pull = do a <- liftIO . atomically $ readTMChan ch-                  case a of-                    Just x -> return $ Open src x-                    Nothing -> return $ Closed-        close = liftIO . atomically $ closeTMChan ch+sourceTMChan ch = chanSource ch readTMChan closeTMChan {-# INLINE sourceTMChan #-} +-- | A simple wrapper around a TBMChan. As data is pushed into the sink, it+--   will magically begin to appear in the channel. If the channel is full,+--   the sink will block until space frees up. When the sink is closed, the+--   channel will close too.+sinkTBMChan :: TBMChan a -> Sink a IO ()+sinkTBMChan ch = chanSink ch writeTBMChan closeTBMChan+{-# INLINE sinkTBMChan #-}+ -- | A simple wrapper around a TMChan. As data is pushed into this sink, it --   will magically begin to appear in the channel. When the sink is closed, --   the channel will close too. sinkTMChan :: TMChan a -> Sink a IO ()-sinkTMChan ch = sink-    where-        sink = SinkData push close-        push input = do liftIO . atomically $ writeTMChan ch input-                        return $ Processing push close-        close = liftIO . atomically $ closeTMChan ch+sinkTMChan ch = chanSink ch writeTMChan closeTMChan {-# INLINE sinkTMChan #-}
stm-conduit.cabal view
@@ -1,5 +1,5 @@ Name:                stm-conduit-Version:             0.2.1+Version:             0.2.2 Synopsis:            Introduces conduits to channels, and promotes using                      conduits concurrently. Description:         Provides two simple conduit wrappers around STM