@@ -29,7 +29,6 @@ module Asyncly.Core
29 , SVarSched (..)
29 , SVarSched (..)
30 , SVarTag (..)
30 , SVarTag (..)
31 , SVarStyle (..)
31 , SVarStyle (..)
33 , newEmptySVar
32 , newEmptySVar
34 , newStreamVar1
33 , newStreamVar1
35 , newStreamVar2
34 , newStreamVar2
@@ -48,7 +47,7 @@ import Control.Concurrent (ThreadId, forkIO,
48 myThreadId, threadDelay)
47 myThreadId, threadDelay)
49import Control.Concurrent.MVar (MVar, newEmptyMVar, tryTakeMVar,
48import Control.Concurrent.MVar (MVar, newEmptyMVar, tryTakeMVar,
50 tryPutMVar, takeMVar)
49 tryPutMVar, takeMVar)
51−import Control.Exception (SomeException (..), Exception)
50+import Control.Exception (SomeException (..))
52import qualified Control.Exception.Lifted as EL
51import qualified Control.Exception.Lifted as EL
53import Control.Monad (MonadPlus(..), mzero, when)
52import Control.Monad (MonadPlus(..), mzero, when)
54import Control.Monad.Base (MonadBase (..), liftBaseDefault)
53import Control.Monad.Base (MonadBase (..), liftBaseDefault)
@@ -321,10 +320,6 @@ sendWorkerWait sv = do
321 then (pushWorker sv) >> sendWorkerWait sv
320 then (pushWorker sv) >> sendWorkerWait sv
322 else void (liftIO $ takeMVar (doorBell sv))
321 else void (liftIO $ takeMVar (doorBell sv))
324−-- | A stream being pulled from 'SVar' has ended.
325−data EndOfStream = EndOfStream deriving Show
326−instance Exception EndOfStream
328-- | Pull a stream from an SVar.
323-- | Pull a stream from an SVar.
329{-# NOINLINE fromStreamVar #-}
324{-# NOINLINE fromStreamVar #-}
330fromStreamVar :: MonadAsync m => SVar m a -> Stream m a
325fromStreamVar :: MonadAsync m => SVar m a -> Stream m a
@@ -332,15 +327,16 @@ fromStreamVar sv = Stream $ \_ stp yld -> do
332 -- XXX if reading the IORef is costly we can use a flag in the SVar to
327 -- XXX if reading the IORef is costly we can use a flag in the SVar to
333 -- indicate we are done.
328 -- indicate we are done.
334 done <- allThreadsDone sv
329 done <- allThreadsDone sv
335− when done $ throwM EndOfStream
330+ if done
337− res <- liftIO $ tryTakeMVar (doorBell sv)
333+ res <- liftIO $ tryTakeMVar (doorBell sv)
338− when (isNothing res) $ sendWorkerWait sv
334+ when (isNothing res) $ sendWorkerWait sv
339− list <- liftIO $ atomicModifyIORefCAS (outputQueue sv) $ \x -> ([], x)
335+ list <- liftIO $ atomicModifyIORefCAS (outputQueue sv) $ \x -> ([], x)
340− -- To avoid lock overhead we read all events at once instead of reading one
336+ -- To avoid lock overhead we read all events at once instead of reading
341− -- at a time. We just reverse the list to process the events in the order
337+ -- one at a time. We just reverse the list to process the events in the
342− -- they arrived. Maybe we can use a queue instead?
338+ -- order they arrived. Maybe we can use a queue instead?
343− (runStream $ processEvents (reverse list)) Nothing stp yld
339+ (runStream $ processEvents (reverse list)) Nothing stp yld