1{-# OPTIONS_GHC -Wno-deprecations #-}
3-- Module : Streamly.Internal.Data.Unfold.SVar
4-- Copyright : (c) 2019 Composewell Technologies
6-- Maintainer : streamly@composewell.com
7-- Stability : experimental
10module Streamly.Internal.Data.Unfold.SVar
19import Control.Exception (fromException)
20import Control.Monad (when)
21import Control.Monad.IO.Class (MonadIO(..))
22import Data.IORef (newIORef, readIORef, mkWeakIORef, writeIORef)
23import Data.Maybe (isNothing)
24import Streamly.Internal.Control.Concurrent (MonadAsync)
25import Streamly.Internal.Data.Stream (Step(..))
26import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
27import Streamly.Internal.Data.SVar (printSVar, cleanupSVar, sendStopToProducer)
28import Streamly.Internal.Data.Unfold (Unfold(..))
29import System.Mem (performMajorGC)
31import qualified Control.Monad.Catch as MC
33import Streamly.Internal.Data.SVar.Type
34-------------------------------------------------------------------------------
35-- Generation from SVar
36-------------------------------------------------------------------------------
38data FromSVarState t m a =
39 FromSVarInit (SVar t m a)
40 | FromSVarRead (SVar t m a)
41 | FromSVarLoop (SVar t m a) [ChildEvent a]
42 | FromSVarDone (SVar t m a)
46{-# INLINE_NORMAL fromSVar #-}
47fromSVar :: MonadAsync m => Unfold m (SVar t m a) a
48fromSVar = Unfold step (return . FromSVarInit)
51 {-# INLINE_LATE step #-}
52 step (FromSVarInit svar) = do
53 ref <- liftIO $ newIORef ()
54 _ <- liftIO $ mkWeakIORef ref hook
55 -- when this copy of svar gets garbage collected "ref" will get
56 -- garbage collected and our GC hook will be called.
57 let sv = svar{svarRef = Just ref}
58 return $ Skip (FromSVarRead sv)
64 when (svarInspectMode svar) $ do
65 r <- liftIO $ readIORef (svarStopTime (svarStats svar))
67 printSVar svar "SVar Garbage Collected"
69 -- If there are any SVars referenced by this SVar a GC will prompt
70 -- them to be cleaned up quickly.
71 when (svarInspectMode svar) performMajorGC
73 step (FromSVarRead sv) = do
74 list <- readOutputQ sv
75 -- Reversing the output is important to guarantee that we process the
76 -- outputs in the same order as they were generated by the constituent
78 return $ Skip $ FromSVarLoop sv (Prelude.reverse list)
80 step (FromSVarLoop sv []) = do
81 done <- postProcess sv
82 return $ Skip $ if done
86 step (FromSVarLoop sv (ev : es)) = do
88 ChildYield a -> return $ Yield a (FromSVarLoop sv es)
93 stop <- shouldStop tid
96 liftIO (cleanupSVar sv)
97 return $ Skip (FromSVarDone sv)
98 else return $ Skip (FromSVarLoop sv es)
100 case fromException ex of
102 return $ Skip (FromSVarLoop sv es)
103 Nothing -> liftIO (cleanupSVar sv) >> MC.throwM ex
107 case svarStopStyle sv of
108 StopNone -> return False
109 StopAny -> return True
111 sid <- liftIO $ readIORef (svarStopBy sv)
114 step (FromSVarDone sv) = do
115 when (svarInspectMode sv) $ do
116 t <- liftIO $ getTime Monotonic
117 liftIO $ writeIORef (svarStopTime (svarStats sv)) (Just t)
118 liftIO $ printSVar sv "SVar Done"
121-------------------------------------------------------------------------------
122-- Process events received by a fold consumer from a stream producer
123-------------------------------------------------------------------------------
125-- XXX Have an error for "FromSVarInit" instead of undefined. The error can
126-- redirect the user to report the failure to the developers.
129{-# INLINE_NORMAL fromProducer #-}
130fromProducer :: MonadAsync m => Unfold m (SVar t m a) a
131fromProducer = Unfold step (return . FromSVarRead)
134 {-# INLINE_LATE step #-}
135 step (FromSVarRead sv) = do
136 list <- readOutputQ sv
137 -- Reversing the output is important to guarantee that we process the
138 -- outputs in the same order as they were generated by the constituent
140 return $ Skip $ FromSVarLoop sv (Prelude.reverse list)
142 step (FromSVarLoop sv []) = return $ Skip $ FromSVarRead sv
143 step (FromSVarLoop sv (ev : es)) = do
145 ChildYield a -> return $ Yield a (FromSVarLoop sv es)
146 ChildStop tid e -> do
150 sendStopToProducer sv
151 return $ Skip (FromSVarDone sv)
152 Just _ -> error "Bug: fromProducer: received exception"
154 step (FromSVarDone sv) = do
155 when (svarInspectMode sv) $ do
156 t <- liftIO $ getTime Monotonic
157 liftIO $ writeIORef (svarStopTime (svarStats sv)) (Just t)
158 liftIO $ printSVar sv "SVar Done"
161 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