@@ -39,13 +39,13 @@ data ConnectionState cdata
3939 | Acquired ! IsolationLevel ! Permissions ! Connection ! cdata
4040 | Finalized
4141
42- -- Note: initConnectionState and finalizeConnectionState are invoked inside
43- -- bracket and run with asynchronous exceptions softly masked. However, both of
44- -- them may run queries that start/finish a transaction. Running queries is a
45- -- blocking (and thus interruptible) operation, but if these queries are
46- -- interrupted with an asynchronous exception, then a connection is leaked, so
47- -- they need to be run with asynchronous exceptions hard masked with
48- -- uninterruptibleMask.
42+ -- Note: initConnection{State,Data} and finalizeConnection{State,Data} need to
43+ -- be invoked inside bracket and run with asynchronous exceptions softly
44+ -- masked. In addition, they may run queries that start/finish a
45+ -- transaction. Running queries is a blocking (and thus interruptible)
46+ -- operation, but if these queries are interrupted with an asynchronous
47+ -- exception, then a connection is leaked, so they need to be run with
48+ -- asynchronous exceptions hard masked with uninterruptibleMask.
4949
5050initConnectionState
5151 :: MonadBase IO m
@@ -146,15 +146,20 @@ changeAcquisitionModeTo
146146 => ConnectionAcquisitionMode
147147 -> ConnectionData m
148148 -> m ()
149- changeAcquisitionModeTo cam ConnectionData {.. } = mask_ $ do
149+ changeAcquisitionModeTo cam ConnectionData {.. } = do
150150 bracketOnError (takeMVar cdConnectionState) (putMVar cdConnectionState) $ \ case
151151 OnDemand -> case cam of
152152 AcquireOnDemand -> putMVar cdConnectionState OnDemand
153- _ -> do
153+ _ -> mask_ $ do
154+ -- Need to mask, if asynchronous exception arrives between
155+ -- initConnectionState and putMVar, the connection leaks.
154156 newConnState <- initConnectionState cdConnectionSource cam
155157 putMVar cdConnectionState newConnState
156158 connState@ (Acquired isolationLevel permissions _ _) -> case cam of
157- AcquireOnDemand -> do
159+ AcquireOnDemand -> mask_ $ do
160+ -- Need to mask, if asynchronous exception arrives between
161+ -- finalizeConnectionState and putMVar, we end up with an invalid
162+ -- (finalized) connection state.
158163 finalizeConnectionState cdConnectionSource (ExitCaseSuccess () ) connState
159164 putMVar cdConnectionState OnDemand
160165 AcquireAndHold newIsolationLevel newPermissions -> do
0 commit comments