diff --git a/library/SlaveThread.hs b/library/SlaveThread.hs
--- a/library/SlaveThread.hs
+++ b/library/SlaveThread.hs
@@ -1,5 +1,5 @@
 -- |
--- Vanilla thread management in Haskell is low level and 
+-- Vanilla thread management in Haskell is low level and
 -- it does not approach the problems related to thread deaths.
 -- When it's used naively the following typical problems arise:
 --
@@ -22,13 +22,13 @@
 -- it kills all the slave threads that were forked from it.
 -- This protects you from ghost threads.
 --
--- 2. It waits for all slaves to die and execute their finalizers 
+-- 2. It waits for all slaves to die and execute their finalizers
 -- before executing its own finalizer and getting released itself.
 -- This gives you hierarchical releasing of resources.
 --
 -- 3. When a slave thread dies with an uncaught exception
 -- it reraises it in the master thread.
--- This protects you from silent exceptions 
+-- This protects you from silent exceptions
 -- and lets you be sure of getting informed
 -- if your program gets brought to an erroneous state.
 module SlaveThread
@@ -49,7 +49,7 @@
 import Control.Monad.Trans.Reader
 import GHC.Conc
 import GHC.Exts (Int(I#), fork#, forkOn#)
-import GHC.IO (IO(IO))
+import GHC.IO (IO(IO), unsafeUnmask)
 import System.IO.Unsafe
 import qualified DeferredFolds.UnfoldlM as UnfoldlM
 import qualified PartialHandler
@@ -75,19 +75,19 @@
 -- Fork a slave thread with a finalizer action to run a computation on.
 -- The finalizer gets executed when the thread dies for whatever reason:
 -- due to being killed or an uncaught exception, or a normal termination.
--- 
+--
 -- Note the order of arguments:
--- 
+--
 -- >forkFinally finalizer computation
 {-# INLINABLE forkFinally #-}
 forkFinally :: IO a -> IO b -> IO ThreadId
 forkFinally finalizer computation =
-  mask $ \unmask -> do
+  mask_ $ do
     masterThread <- myThreadId
     -- Ensures that the thread gets registered before being unregistered
     registrationGate <- newEmptyMVar
     slaveThread <-
-      forkIOWithoutHandler $ do
+      forkIOWithUnmaskWithoutHandler $ \unmask -> do
         slaveThread <- myThreadId
         catch
           (unmask (void computation))
@@ -122,9 +122,9 @@
     unless null retry
 
 -- |
--- A more efficient version of 'forkIO', 
+-- A more efficient version of 'forkIOWithUnmask',
 -- which does not install a default exception handler on the forked thread.
-{-# INLINE forkIOWithoutHandler #-}
-forkIOWithoutHandler :: IO () -> IO ThreadId
-forkIOWithoutHandler action = 
-  IO $ \s -> case (fork# action s) of (# s', tid #) -> (# s', ThreadId tid #)
+{-# INLINE forkIOWithUnmaskWithoutHandler #-}
+forkIOWithUnmaskWithoutHandler :: ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId
+forkIOWithUnmaskWithoutHandler action =
+  IO $ \s -> case (fork# (action unsafeUnmask)  s) of (# s', tid #) -> (# s', ThreadId tid #)
diff --git a/slave-thread.cabal b/slave-thread.cabal
--- a/slave-thread.cabal
+++ b/slave-thread.cabal
@@ -1,5 +1,5 @@
 name: slave-thread
-version: 1.0.2.4
+version: 1.0.2.5
 synopsis: A fundamental solution to ghost threads and silent exceptions
 description:
   Vanilla thread management in Haskell is low level and 
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,7 +1,6 @@
 module Main where
 
 import Prelude
-import Control.Concurrent.STM
 import Test.QuickCheck.Instances
 import Test.Tasty
 import Test.Tasty.Runners
@@ -124,6 +123,11 @@
         takeMVar ready
         killThread thread
         assertEqual "First finalizer is not slave" 0 =<< atomically (readTMVar var)
+    ,
+    testCase "Forked threads don't inherit the masking state" $ do
+      var <- newEmptyMVar
+      mask_ (S.fork (getMaskingState >>= putMVar var))
+      assertEqual "" Unmasked =<< takeMVar var
   ]
 
 forkWait :: IO a -> IO (IO ())
@@ -131,7 +135,7 @@
   do
     v <- newEmptyMVar
     S.fork $ do
-      r <- try io
+      r <- try @SomeException io
       putMVar v ()
-      either (throwIO @SomeException) return r
+      either throwIO return r
     return $ takeMVar v
