2-- Module : Streamly.Internal.Data.Unfold.SVar
3-- Copyright : (c) 2019 Composewell Technologies
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
9module Streamly.Internal.Data.Unfold.SVar
18import Control.Exception (fromException)
19import Control.Monad (when)
20import Control.Monad.IO.Class (MonadIO(..))
21import Data.IORef (newIORef, readIORef, mkWeakIORef, writeIORef)
22import Data.Maybe (isNothing)
23import Streamly.Internal.Control.Concurrent (MonadAsync)
24import Streamly.Internal.Data.Stream.StreamD.Type (Step(..))
25import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
26import Streamly.Internal.Data.SVar (printSVar, cleanupSVar, sendStopToProducer)
27import Streamly.Internal.Data.Unfold.Type (Unfold(..))
28import System.Mem (performMajorGC)
30import qualified Control.Monad.Catch as MC
32import Streamly.Internal.Data.SVar.Type
33-------------------------------------------------------------------------------
34-- Generation from SVar
35-------------------------------------------------------------------------------
37data FromSVarState t m a =
38 FromSVarInit (SVar t m a)
39 | FromSVarRead (SVar t m a)
40 | FromSVarLoop (SVar t m a) [ChildEvent a]
41 | FromSVarDone (SVar t m a)
45{-# INLINE_NORMAL fromSVar #-}
46fromSVar :: MonadAsync m => Unfold m (SVar t m a) a
47fromSVar = Unfold step (return . FromSVarInit)
50 {-# INLINE_LATE step #-}
51 step (FromSVarInit svar) = do
52 ref <- liftIO $ newIORef ()
53 _ <- liftIO $ mkWeakIORef ref hook
54 -- when this copy of svar gets garbage collected "ref" will get
55 -- garbage collected and our GC hook will be called.
56 let sv = svar{svarRef = Just ref}
57 return $ Skip (FromSVarRead sv)
63 when (svarInspectMode svar) $ do
64 r <- liftIO $ readIORef (svarStopTime (svarStats svar))
66 printSVar svar "SVar Garbage Collected"
68 -- If there are any SVars referenced by this SVar a GC will prompt
69 -- them to be cleaned up quickly.
70 when (svarInspectMode svar) performMajorGC
72 step (FromSVarRead sv) = do
73 list <- readOutputQ sv
74 -- Reversing the output is important to guarantee that we process the
75 -- outputs in the same order as they were generated by the constituent
77 return $ Skip $ FromSVarLoop sv (Prelude.reverse list)
79 step (FromSVarLoop sv []) = do
80 done <- postProcess sv
81 return $ Skip $ if done
85 step (FromSVarLoop sv (ev : es)) = do
87 ChildYield a -> return $ Yield a (FromSVarLoop sv es)
92 stop <- shouldStop tid
95 liftIO (cleanupSVar sv)
96 return $ Skip (FromSVarDone sv)
97 else return $ Skip (FromSVarLoop sv es)
99 case fromException ex of
101 return $ Skip (FromSVarLoop sv es)
102 Nothing -> liftIO (cleanupSVar sv) >> MC.throwM ex
106 case svarStopStyle sv of
107 StopNone -> return False
108 StopAny -> return True
110 sid <- liftIO $ readIORef (svarStopBy sv)
113 step (FromSVarDone sv) = do
114 when (svarInspectMode sv) $ do
115 t <- liftIO $ getTime Monotonic
116 liftIO $ writeIORef (svarStopTime (svarStats sv)) (Just t)
117 liftIO $ printSVar sv "SVar Done"
120-------------------------------------------------------------------------------
121-- Process events received by a fold consumer from a stream producer
122-------------------------------------------------------------------------------
124-- XXX Have an error for "FromSVarInit" instead of undefined. The error can
125-- redirect the user to report the failure to the developers.
128{-# INLINE_NORMAL fromProducer #-}
129fromProducer :: MonadAsync m => Unfold m (SVar t m a) a
130fromProducer = Unfold step (return . FromSVarRead)
133 {-# INLINE_LATE step #-}
134 step (FromSVarRead sv) = do
135 list <- readOutputQ sv
136 -- Reversing the output is important to guarantee that we process the
137 -- outputs in the same order as they were generated by the constituent
139 return $ Skip $ FromSVarLoop sv (Prelude.reverse list)
141 step (FromSVarLoop sv []) = return $ Skip $ FromSVarRead sv
142 step (FromSVarLoop sv (ev : es)) = do
144 ChildYield a -> return $ Yield a (FromSVarLoop sv es)
145 ChildStop tid e -> do
149 sendStopToProducer sv
150 return $ Skip (FromSVarDone sv)
151 Just _ -> error "Bug: fromProducer: received exception"
153 step (FromSVarDone sv) = do
154 when (svarInspectMode sv) $ do
155 t <- liftIO $ getTime Monotonic
156 liftIO $ writeIORef (svarStopTime (svarStats sv)) (Just t)
157 liftIO $ printSVar sv "SVar Done"
160 step (FromSVarInit _) = undefined
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list