diff --git a/pipes-concurrency.cabal b/pipes-concurrency.cabal
--- a/pipes-concurrency.cabal
+++ b/pipes-concurrency.cabal
@@ -1,5 +1,5 @@
 Name: pipes-concurrency
-Version: 2.0.7
+Version: 2.0.8
 Cabal-Version: >=1.8.0.2
 Build-Type: Simple
 License: BSD3
@@ -31,11 +31,12 @@
 Library
     Hs-Source-Dirs: src
     Build-Depends:
-        base          >= 4     && < 5  ,
-        contravariant >= 1.3.3 && < 1.5,
-        pipes         >= 4.0   && < 4.4,
-        stm           >= 2.4.3 && < 2.5,
-        void          >= 0.6   && < 1
+        base          >= 4       && < 5  ,
+        async         >= 2.0.0.0 && < 2.2,
+        contravariant >= 1.3.3   && < 1.5,
+        pipes         >= 4.0     && < 4.4,
+        stm           >= 2.4.3   && < 2.5,
+        void          >= 0.6     && < 1
     Exposed-Modules:
         Pipes.Concurrent,
         Pipes.Concurrent.Tutorial
@@ -48,6 +49,6 @@
     Build-Depends:
         base              >= 4     && < 5  ,
         pipes             >= 4.0.0 && < 4.4,
-        pipes-concurrency >= 2.0.0 && < 2.1,
+        pipes-concurrency                  ,
         stm               >= 2.4.3 && < 2.5,
         async             >= 2.0   && < 2.2
diff --git a/src/Pipes/Concurrent.hs b/src/Pipes/Concurrent.hs
--- a/src/Pipes/Concurrent.hs
+++ b/src/Pipes/Concurrent.hs
@@ -15,6 +15,7 @@
     spawn,
     spawn',
     withSpawn,
+    withBuffer,
     Buffer(..),
     unbounded,
     bounded,
@@ -32,7 +33,6 @@
     Alternative(empty, (<|>)), Applicative(pure, (*>), (<*>)), (<*), (<$>) )
 import Control.Concurrent (forkIO)
 import Control.Concurrent.STM (atomically, STM, mkWeakTVar, newTVarIO, readTVar)
-import qualified Control.Concurrent.STM as S
 import Control.Exception (bracket)
 import Control.Monad (when,void, MonadPlus(..))
 import Data.Functor.Contravariant (Contravariant(contramap))
@@ -43,6 +43,10 @@
 import Pipes (MonadIO(liftIO), yield, await, Producer', Consumer')
 import System.Mem (performGC)
 
+import qualified Control.Concurrent.Async
+import qualified Control.Concurrent.STM   as S
+import qualified Control.Exception
+
 {-| An exhaustible source of values
 
     'recv' returns 'Nothing' if the source is exhausted
@@ -239,6 +243,21 @@
     (\(_, _, seal) -> atomically seal)
     (\(output, input, _) -> action (output, input))
 
+-- | A more restrictive alternative to `withSpawn` that prevents deadlocks
+withBuffer
+    :: Buffer a
+    -> (Output a -> IO l)
+    -> (Input  a -> IO r)
+    -> IO (l, r)
+withBuffer buffer fOutput fInput = bracket
+  (spawn' buffer)
+  (\(_, _, seal) -> atomically seal)
+  (\(output, input, seal) ->
+    Control.Concurrent.Async.concurrently
+      (fOutput output `Control.Exception.finally` atomically seal)
+      (fInput  input  `Control.Exception.finally` atomically seal)
+  )
+
 -- | 'Buffer' specifies how to buffer messages stored within the mailbox
 data Buffer a
     = Unbounded
@@ -272,7 +291,7 @@
 latest = Latest
 
 {-| Like @Bounded@, but 'send' never fails (the buffer is never full).
-    Instead, old elements are discard to make room for new elements
+    Instead, old elements are discarded to make room for new elements
 -}
 newest :: Int -> Buffer a
 newest 1 = New
diff --git a/tests/tests-main.hs b/tests/tests-main.hs
--- a/tests/tests-main.hs
+++ b/tests/tests-main.hs
@@ -11,7 +11,7 @@
 import System.Timeout
 
 defaultTimeout :: Int
-defaultTimeout = 200000         -- 0.2 s
+defaultTimeout = 1000000  -- 1 second
 
 labelPrint :: (Show a) => String -> Consumer a IO r
 labelPrint label = forever $ do
