diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # ChangeLog for typed-process
 
+## Unreleased
+
+* The cleanup thread applies an `unmask` to the actions which wait for a
+  process to exit, allowing the action to be interruptible.
+
 ## 0.2.5.0
 
 * Add a `nullStream` [#24](https://github.com/fpco/typed-process/pull/24)
diff --git a/src/System/Process/Typed.hs b/src/System/Process/Typed.hs
--- a/src/System/Process/Typed.hs
+++ b/src/System/Process/Typed.hs
@@ -97,7 +97,8 @@
 
 import qualified Data.ByteString as S
 import Data.ByteString.Lazy.Internal (defaultChunkSize)
-import Control.Exception (assert, evaluate, throwIO, Exception, SomeException, finally, bracket, onException, catch, try)
+import qualified Control.Exception as E
+import Control.Exception hiding (bracket, finally)
 import Control.Monad (void)
 import Control.Monad.IO.Class
 import qualified System.Process as P
@@ -105,7 +106,7 @@
 import System.IO (Handle, hClose, IOMode(ReadWriteMode), withBinaryFile)
 import System.IO.Error (isPermissionError)
 import Control.Concurrent (threadDelay)
-import Control.Concurrent.Async (async, cancel, waitCatch)
+import Control.Concurrent.Async (async, asyncWithUnmask, cancel, waitCatch)
 import Control.Concurrent.STM (newEmptyTMVarIO, atomically, putTMVar, TMVar, readTMVar, tryReadTMVar, STM, tryPutTMVar, throwSTM, catchSTM)
 import System.Exit (ExitCode (ExitSuccess))
 import System.Process.Typed.Internal
@@ -113,6 +114,7 @@
 import qualified Data.ByteString.Lazy.Char8 as L8
 import Data.String (IsString (fromString))
 import GHC.RTS.Flags (getConcFlags, ctxtSwitchTime)
+import Control.Monad.IO.Unlift
 
 #if MIN_VERSION_process(1, 4, 0) && !WINDOWS
 import System.Posix.Types (GroupID, UserID)
@@ -667,8 +669,8 @@
               <*> ssCreate pcStderr pConfig merrH
 
           pExitCode <- newEmptyTMVarIO
-          waitingThread <- async $ do
-              ec <-
+          waitingThread <- asyncWithUnmask $ \unmask -> do
+              ec <- unmask $ -- make sure the masking state from a bracket isn't inherited
                 if multiThreadedRuntime
                   then P.waitForProcess pHandle
                   else do
@@ -759,10 +761,10 @@
 -- <https://github.com/fpco/typed-process/issues/25>.
 --
 -- @since 0.2.5.0
-withProcessTerm
-  :: ProcessConfig stdin stdout stderr
-  -> (Process stdin stdout stderr -> IO a)
-  -> IO a
+withProcessTerm :: (MonadUnliftIO m)
+  => ProcessConfig stdin stdout stderr
+  -> (Process stdin stdout stderr -> m a)
+  -> m a
 withProcessTerm config = bracket (startProcess config) stopProcess
 
 -- | Uses the bracket pattern to call 'startProcess'. Unlike
@@ -771,10 +773,10 @@
 -- inner function throws an exception.
 --
 -- @since 0.2.5.0
-withProcessWait
-  :: ProcessConfig stdin stdout stderr
-  -> (Process stdin stdout stderr -> IO a)
-  -> IO a
+withProcessWait :: (MonadUnliftIO m)
+  => ProcessConfig stdin stdout stderr
+  -> (Process stdin stdout stderr -> m a)
+  -> m a
 withProcessWait config f =
   bracket
     (startProcess config)
@@ -784,19 +786,20 @@
 -- | Deprecated synonym for 'withProcessTerm'.
 --
 -- @since 0.1.0.0
-withProcess :: ProcessConfig stdin stdout stderr
-            -> (Process stdin stdout stderr -> IO a)
-            -> IO a
+withProcess :: (MonadUnliftIO m)
+  => ProcessConfig stdin stdout stderr
+  -> (Process stdin stdout stderr -> m a)
+  -> m a
 withProcess = withProcessTerm
 {-# DEPRECATED withProcess "Please consider using withProcessWait, or instead use withProcessTerm" #-}
 
 -- | Same as 'withProcessTerm', but also calls 'checkExitCode'
 --
 -- @since 0.2.5.0
-withProcessTerm_
-  :: ProcessConfig stdin stdout stderr
-  -> (Process stdin stdout stderr -> IO a)
-  -> IO a
+withProcessTerm_ :: (MonadUnliftIO m)
+  => ProcessConfig stdin stdout stderr
+  -> (Process stdin stdout stderr -> m a)
+  -> m a
 withProcessTerm_ config = bracket
     (startProcess config)
     (\p -> stopProcess p `finally` checkExitCode p)
@@ -804,10 +807,10 @@
 -- | Same as 'withProcessWait', but also calls 'checkExitCode'
 --
 -- @since 0.2.5.0
-withProcessWait_
-  :: ProcessConfig stdin stdout stderr
-  -> (Process stdin stdout stderr -> IO a)
-  -> IO a
+withProcessWait_ :: (MonadUnliftIO m)
+  => ProcessConfig stdin stdout stderr
+  -> (Process stdin stdout stderr -> m a)
+  -> m a
 withProcessWait_ config f = bracket
     (startProcess config)
     stopProcess
@@ -816,9 +819,10 @@
 -- | Deprecated synonym for 'withProcessTerm_'.
 --
 -- @since 0.1.0.0
-withProcess_ :: ProcessConfig stdin stdout stderr
-             -> (Process stdin stdout stderr -> IO a)
-             -> IO a
+withProcess_ :: (MonadUnliftIO m)
+  => ProcessConfig stdin stdout stderr
+  -> (Process stdin stdout stderr -> m a)
+  -> m a
 withProcess_ = withProcessTerm_
 {-# DEPRECATED withProcess_ "Please consider using withProcessWait_, or instead use withProcessTerm_" #-}
 
@@ -933,10 +937,10 @@
   where
     pc' = setStderr byteStringOutput pc
 
-withProcessInterleave
-  :: ProcessConfig stdin stdoutIgnored stderrIgnored
-  -> (Process stdin (STM L.ByteString) () -> IO a)
-  -> IO a
+withProcessInterleave :: (MonadUnliftIO m)
+  => ProcessConfig stdin stdoutIgnored stderrIgnored
+  -> (Process stdin (STM L.ByteString) () -> m a)
+  -> m a
 withProcessInterleave pc inner =
     -- Create a pipe to be shared for both stdout and stderr
     bracket P.createPipe (\(r, w) -> hClose r >> hClose w) $ \(readEnd, writeEnd) -> do
@@ -949,7 +953,7 @@
         withProcess pc' $ \p -> do
           -- Now that the process is forked, close the writer end of this
           -- pipe, otherwise the reader end will never give an EOF.
-          hClose writeEnd
+          liftIO $ hClose writeEnd
           inner p
 
 -- | Same as 'readProcess', but interleaves stderr with stdout.
@@ -1142,3 +1146,9 @@
 -- @since 0.1.1
 unsafeProcessHandle :: Process stdin stdout stderr -> P.ProcessHandle
 unsafeProcessHandle = pHandle
+
+bracket :: MonadUnliftIO m => IO a -> (a -> IO b) -> (a -> m c) -> m c
+bracket before after thing = withRunInIO $ \run -> E.bracket before after (run . thing)
+
+finally :: MonadUnliftIO m => m a -> IO () -> m a
+finally thing after = withRunInIO $ \run -> E.finally (run thing) after
diff --git a/test/System/Process/TypedSpec.hs b/test/System/Process/TypedSpec.hs
--- a/test/System/Process/TypedSpec.hs
+++ b/test/System/Process/TypedSpec.hs
@@ -112,14 +112,14 @@
         raw <- S.readFile fp
         encoded `shouldBe` B64.encode raw
 
-    describe "withProcessWait" $ do
+    describe "withProcessWait" $
         it "succeeds with sleep" $ do
           p <- withProcessWait (proc "sleep" ["1"]) pure
-          checkExitCode p
+          checkExitCode p :: IO ()
 
-    describe "withProcessWait_" $ do
-        it "succeeds with sleep" $ do
-          withProcessWait_ (proc "sleep" ["1"]) $ const $ pure ()
+    describe "withProcessWait_" $
+        it "succeeds with sleep"
+           ((withProcessWait_ (proc "sleep" ["1"]) $ const $ pure ()) :: IO ())
 
     -- These tests fail on older GHCs/process package versions
     -- because, apparently, waitForProcess isn't interruptible. See
diff --git a/typed-process.cabal b/typed-process.cabal
--- a/typed-process.cabal
+++ b/typed-process.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: ad27eee8ecda9f23b7e99ea05885ad76c916b5210115a132a56a28c79437d01c
+-- hash: f8fdbd0397d67fa0c8d6c96e3e95d3d6eb56d94fc13f0350fc60ff855d44d671
 
 name:           typed-process
-version:        0.2.5.0
+version:        0.2.6.0
 synopsis:       Run external processes, with strong typing of streams
 description:    Please see the tutorial at <https://haskell-lang.org/library/typed-process>
 category:       System
@@ -41,6 +41,7 @@
     , process >=1.2
     , stm
     , transformers
+    , unliftio-core
   if os(windows)
     cpp-options: -DWINDOWS
   default-language: Haskell2010
@@ -65,6 +66,7 @@
     , temporary
     , transformers
     , typed-process
+    , unliftio-core
   default-language: Haskell2010
 
 test-suite typed-process-test-single-threaded
@@ -86,4 +88,5 @@
     , temporary
     , transformers
     , typed-process
+    , unliftio-core
   default-language: Haskell2010
