diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,12 @@
+concurrent-output (1.10.13) unstable; urgency=medium
+
+  * outputConcurrent and errorConcurrent are now safe to call from a thread
+    that receives async exceptions.
+  * Fix compilation with GHC head.
+    (Thanks, Ellie Hermaszewska)
+
+ -- Joey Hess <id@joeyh.name>  Mon, 22 Nov 2021 11:19:21 -0400
+
 concurrent-output (1.10.12) unstable; urgency=medium
 
   * Bugfix: createProcessConcurrent would sometimes send the process's
diff --git a/System/Console/Concurrent/Internal.hs b/System/Console/Concurrent/Internal.hs
--- a/System/Console/Concurrent/Internal.hs
+++ b/System/Console/Concurrent/Internal.hs
@@ -168,7 +168,12 @@
 errorConcurrent = outputConcurrent' StdErr
 
 outputConcurrent' :: Outputable v => StdHandle -> v -> IO ()
-outputConcurrent' stdh v = bracket setup cleanup go
+outputConcurrent' stdh v = do
+	-- Use a worker thread. This is so any async exception that
+	-- is thrown to the current thread does not affect
+	-- tryTakeOutputLock, which is not async exception safe.
+	worker <- async $ bracket setup cleanup go
+	wait worker
   where
 	setup = tryTakeOutputLock
 	cleanup False = return ()
diff --git a/System/Console/Regions.hs b/System/Console/Regions.hs
--- a/System/Console/Regions.hs
+++ b/System/Console/Regions.hs
@@ -130,7 +130,7 @@
 import System.IO
 import System.IO.Unsafe (unsafePerformIO)
 import Text.Read
-import Data.List
+import Data.List (intercalate, nubBy)
 #ifndef mingw32_HOST_OS
 import System.Posix.Signals
 import System.Posix.Signals.Exts
diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -3,7 +3,25 @@
   If a thread is running an action from that module and an async exception
   is sent to it, it may result in a deadlock or other problem.
 
-  (System.Console.Regions has been made safe.)
+  (System.Console.Regions has been made safe,
+  also outputConcurrent and errorConcurrent.)
+
+  Particularly problematic is takeOutputLock', which takes the lock
+  and then outputs buffers to the console. If the emitOutputBuffer
+  calls are interrupted by async exception, it will be left locked
+  and the buffered output is also lost. But masking them is not good
+  because emitOutputBuffer could run for a long time in some situations.
+
+  fgProcess and bgProcess also do stuff with registerOutputThread/unregisterOutputThread
+  that may not be async exception safe. 
+
+  And createProcessForeground uses takeOutputLock but then calls fgProcess,
+  which could be interrupted (during its call to registerOutputThread)
+  before it starts the async thread that drops the lock.
+
+  One approach to all this might be to fork off a worker thread,
+  which will thus be immune to any async exception directed at the calling
+  thread.
 
 * Calling setConsoleRegion with something that throws an error
   will cause no further display updates to happen.
diff --git a/concurrent-output.cabal b/concurrent-output.cabal
--- a/concurrent-output.cabal
+++ b/concurrent-output.cabal
@@ -1,11 +1,11 @@
 Name: concurrent-output
-Version: 1.10.12
+Version: 1.10.13
 Cabal-Version: >= 1.10
 License: BSD2
 Maintainer: Joey Hess <id@joeyh.name>
 Author: Joey Hess, Joachim Breitner
 Stability: Stable
-Copyright: 2015-2020 Joey Hess, 2009 Joachim Breitner
+Copyright: 2015-2021 Joey Hess, 2009 Joachim Breitner
 License-File: LICENSE
 Build-Type: Simple
 Category: User Interfaces
@@ -29,7 +29,7 @@
   stmdemo.hs
 
 Library
-  Default-Language: Haskell98
+  Default-Language: Haskell2010
   GHC-Options: -Wall -fno-warn-tabs -O2
   Build-Depends: base (>= 4.6), base < 5
     , text (>= 0.11.0 && < 1.3.0)
