diff --git a/src/Control/Concurrent/ThreadManager.hs b/src/Control/Concurrent/ThreadManager.hs
--- a/src/Control/Concurrent/ThreadManager.hs
+++ b/src/Control/Concurrent/ThreadManager.hs
@@ -15,9 +15,9 @@
   ) where
 
 import Control.Concurrent      (ThreadId, forkIO)
-import Control.Concurrent.MVar (MVar, modifyMVar, newEmptyMVar, newMVar, putMVar, takeMVar, tryTakeMVar)
+import Control.Concurrent.MVar (MVar, modifyMVar, newEmptyMVar, newMVar, putMVar, takeMVar, tryTakeMVar, readMVar)
 import Control.Exception       (SomeException, try)
-import Control.Monad           (join, replicateM)
+import Control.Monad           (join, replicateM, when)
 import qualified Data.Map as M
 
 data ThreadStatus =
@@ -70,7 +70,15 @@
 
 -- | Block until all managed threads terminate.
 waitForAll :: ThreadManager -> IO ()
-waitForAll (TM tm) =
-    modifyMVar tm elems >>= mapM_ takeMVar
+waitForAll tm@(TM tmMvar) = do
+    threadMap <- readMVar tmMvar
+    let threads = M.keys threadMap
+    statuses <- mapM (getStatus tm) threads
+    _ <- mapM (waitFor tm) threads
+    Control.Monad.when (foldr checkStatus False statuses) $
+        waitForAll tm
   where
-    elems m = return (M.empty, M.elems m)
+    checkStatus :: Maybe ThreadStatus -> Bool -> Bool
+    checkStatus _ True = True
+    checkStatus (Just Running) False = True
+    checkStatus _ False = False
diff --git a/threadmanager.cabal b/threadmanager.cabal
--- a/threadmanager.cabal
+++ b/threadmanager.cabal
@@ -1,5 +1,5 @@
 name:    threadmanager
-version: 0.1.4
+version: 0.1.5
 
 category: Concurrency
 
@@ -24,7 +24,7 @@
 library
     hs-source-dirs:  src
     exposed-modules: Control.Concurrent.ThreadManager
-    build-depends:   base == 4.*, containers >= 0.2.0.0 && <= 0.4.0.0
+    build-depends:   base >= 3 && < 5, containers
     ghc-options:     -Wall
     if impl(ghc >= 6.8)
         ghc-options: -fwarn-tabs
