diff --git a/Control/Concurrent/BroadcastChan.hs b/Control/Concurrent/BroadcastChan.hs
--- a/Control/Concurrent/BroadcastChan.hs
+++ b/Control/Concurrent/BroadcastChan.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE Safe #-}
 -------------------------------------------------------------------------------
 -- |
 -- Module      :  Contro.Concurrent.BroadcastChan
@@ -50,11 +50,8 @@
 type Out = 'Out
 
 -- | The abstract type representing the read or write end of a 'BroadcastChan'.
-data BroadcastChan :: Direction -> * -> * where
-    WriteEnd :: {-# UNPACK #-} !(MVar (Stream a)) -> BroadcastChan In a
-    ReadEnd  :: {-# UNPACK #-} !(MVar (Stream a)) -> BroadcastChan Out a
-
-deriving instance Eq (BroadcastChan i a)
+newtype BroadcastChan (d :: Direction) a = BChan (MVar (Stream a))
+    deriving (Eq)
 
 type Stream a = MVar (ChItem a)
 
@@ -65,13 +62,13 @@
 newBroadcastChan = do
    hole  <- newEmptyMVar
    writeVar <- newMVar hole
-   return (WriteEnd writeVar)
+   return (BChan writeVar)
 
 -- | Write a value to write end of a 'BroadcastChan'. Any messages written
 -- while there are no live read ends can be immediately garbage collected, thus
 -- avoiding space leaks.
 writeBChan :: BroadcastChan In a -> a -> IO ()
-writeBChan (WriteEnd writeVar) val = do
+writeBChan (BChan writeVar) val = do
   new_hole <- newEmptyMVar
   mask_ $ do
     old_hole <- takeMVar writeVar
@@ -80,17 +77,25 @@
 
 -- | Read the next value from the read end of a 'BroadcastChan'.
 readBChan :: BroadcastChan Out a -> IO a
-readBChan (ReadEnd readVar) = do
+readBChan (BChan readVar) = do
   modifyMVarMasked readVar $ \read_end -> do -- Note [modifyMVarMasked]
     (ChItem val new_read_end) <- readMVar read_end
         -- Use readMVar here, not takeMVar,
         -- else dupBroadcastChan doesn't work
     return (new_read_end, val)
 
+-- Note [modifyMVarMasked]
+-- This prevents a theoretical deadlock if an asynchronous exception
+-- happens during the readMVar while the MVar is empty.  In that case
+-- the read_end MVar will be left empty, and subsequent readers will
+-- deadlock.  Using modifyMVarMasked prevents this.  The deadlock can
+-- be reproduced, but only by expanding readMVar and inserting an
+-- artificial yield between its takeMVar and putMVar operations.
+
 -- | Create a new read end for a 'BroadcastChan'. Will receive all messages
 -- written to the channel's write end after the read end's creation.
 newBChanListener :: BroadcastChan In a -> IO (BroadcastChan Out a)
-newBChanListener (WriteEnd writeVar) = do
+newBChanListener (BChan writeVar) = do
    hole       <- readMVar writeVar
    newReadVar <- newMVar hole
-   return (ReadEnd newReadVar)
+   return (BChan newReadVar)
diff --git a/broadcast-chan.cabal b/broadcast-chan.cabal
--- a/broadcast-chan.cabal
+++ b/broadcast-chan.cabal
@@ -1,5 +1,5 @@
 Name:                broadcast-chan
-Version:             0.1.0
+Version:             0.1.1
 
 Homepage:            https://github.com/merijn/broadcast-chan
 Bug-Reports:         https://github.com/merijn/broadcast-chan/issues
@@ -36,15 +36,18 @@
 Library
   Default-Language:     Haskell2010
   GHC-Options:          -Wall -fno-warn-unused-do-bind
-  GHC-Prof-Options:     -auto-all -caf-all -rtsopts
   Exposed-Modules:      Control.Concurrent.BroadcastChan
 
   Build-Depends:        base >= 4 && < 5
 
 Source-Repository head
+  Type:     git
+  Location: ssh://github.com:merijn/broadcast-chan.git
+
+Source-Repository head
   Type:     mercurial
-  Location: https://bitbucket.org/merijnv/broadcast-chan
+  Location: git+ssh://github.com:merijn/broadcast-chan.git
 
 Source-Repository head
   Type:     mercurial
-  Location: git+ssh://github.com:merijn/broadcast-chan
+  Location: https://bitbucket.org/merijnv/broadcast-chan
