@@ -182,38 +182,26 @@ withVar (Var x) f = withMVar x f
182
182
-- for it to complete. A barrier has similarities to a future or promise
183
183
-- from other languages, has been known as an IVar in other Haskell work,
184
184
-- and in some ways is like a manually managed thunk.
185
- newtype Barrier a = Barrier (Var (Either (MVar () ) a ))
186
- -- Either a Left empty MVar you should wait or a Right result
187
- -- With base 4.7 and above readMVar is atomic so you probably can implement Barrier directly on MVar a
185
+ newtype Barrier a = Barrier (MVar a )
188
186
189
187
-- | Create a new 'Barrier'.
190
188
newBarrier :: IO (Barrier a )
191
- newBarrier = fmap Barrier $ newVar . Left =<< newEmptyMVar
189
+ newBarrier = Barrier <$> newEmptyMVar
192
190
193
191
-- | Write a value into the Barrier, releasing anyone at 'waitBarrier'.
194
192
-- Any subsequent attempts to signal the 'Barrier' will throw an exception.
195
193
signalBarrier :: Partial => Barrier a -> a -> IO ()
196
- signalBarrier (Barrier var) v = mask_ $ -- use mask so never in an inconsistent state
197
- join $ modifyVar var $ \ x -> case x of
198
- Left bar -> pure (Right v, putMVar bar () )
199
- Right res -> error " Control.Concurrent.Extra.signalBarrier, attempt to signal a barrier that has already been signaled"
194
+ signalBarrier (Barrier var) v = do
195
+ b <- tryPutMVar var v
196
+ unless b $ errorIO " Control.Concurrent.Extra.signalBarrier, attempt to signal a barrier that has already been signaled"
200
197
201
198
202
199
-- | Wait until a barrier has been signaled with 'signalBarrier'.
203
200
waitBarrier :: Barrier a -> IO a
204
- waitBarrier (Barrier var) = do
205
- x <- readVar var
206
- case x of
207
- Right res -> pure res
208
- Left bar -> do
209
- readMVar bar
210
- x <- readVar var
211
- case x of
212
- Right res -> pure res
213
- Left bar -> error " Control.Concurrent.Extra, internal invariant violated in Barrier"
201
+ waitBarrier (Barrier var) = readMVar var
214
202
215
203
216
204
-- | A version of 'waitBarrier' that never blocks, returning 'Nothing'
217
205
-- if the barrier has not yet been signaled.
218
206
waitBarrierMaybe :: Barrier a -> IO (Maybe a )
219
- waitBarrierMaybe (Barrier bar) = eitherToMaybe <$> readVar bar
207
+ waitBarrierMaybe (Barrier bar) = tryReadMVar bar
0 commit comments