@@ -68,7 +68,7 @@ data WorkerStatus = Continue | Suspend
6868{-# INLINE workLoopLIFO #-}
6969workLoopLIFO
7070 :: (MonadIO m, MonadBaseControl IO m)
71− => IORef [Stream m a]
71+ => IORef [(RunInIO m, Stream m a)]
7272 -> State Stream m a
7373 -> SVar Stream m a
7474 -> Maybe WorkerInfo
@@ -77,13 +77,12 @@ workLoopLIFO q st sv winfo = run
7777
7878 where
7979
80− mrun = runInIO $ svarMrun sv
80+ stop = liftIO $ sendStop sv winfo
8181 run = do
8282 work <- dequeue
83− let stop = liftIO $ sendStop sv winfo
8483 case work of
8584 Nothing -> stop
86− Just m -> do
85+ Just (RunInIO runin, m) -> do
8786 -- XXX when we finish we need to send the monadic state back to
8887 -- the parent so that the state can be merged back. We capture
8988 -- and return the state in the stop continuation.
@@ -91,7 +90,7 @@ workLoopLIFO q st sv winfo = run
9190 -- Instead of using the run function we can just restore the
9291 -- monad state here. That way it can work easily for
9392 -- distributed case as well.
94− r <- liftIO $ mrun $
93+ r <- liftIO $ runin $
9594 foldStreamShared st yieldk single (return Continue) m
9695 res <- restoreM r
9796 case res of
@@ -106,9 +105,9 @@ workLoopLIFO q st sv winfo = run
106105 res <- liftIO $ sendYield sv winfo (ChildYield a)
107106 if res
108107 then foldStreamShared st yieldk single (return Continue) r
109− else liftIO $ do
110− -- XXX we also need to save the monadic state here
111− enqueueLIFO sv q r
108+ else do
109+ runInIO <- captureMonadState
110+ liftIO $ enqueueLIFO sv q (runInIO, r)
112111 return Suspend
113112
114113 dequeue = liftIO $ atomicModifyIORefCAS q $ \case
@@ -122,8 +121,8 @@ workLoopLIFO q st sv winfo = run
122121-- make a check every time.
123122{-# INLINE workLoopLIFOLimited #-}
124123workLoopLIFOLimited
125− :: (MonadIO m, MonadBaseControl IO m)
126− => IORef [Stream m a]
124+ :: forall m a. (MonadIO m, MonadBaseControl IO m)
125+ => IORef [(RunInIO m, Stream m a)]
127126 -> State Stream m a
128127 -> SVar Stream m a
129128 -> Maybe WorkerInfo
@@ -132,14 +131,13 @@ workLoopLIFOLimited q st sv winfo = run
132131
133132 where
134133
135− mrun = runInIO $ svarMrun sv
136134 incrContinue = liftIO (incrementYieldLimit sv) >> return Continue
135+ stop = liftIO $ sendStop sv winfo
137136 run = do
138137 work <- dequeue
139− let stop = liftIO $ sendStop sv winfo
140138 case work of
141139 Nothing -> stop
142− Just m -> do
140+ Just (RunInIO runin, m) -> do
143141 -- XXX This is just a best effort minimization of concurrency
144142 -- to the yield limit. If the stream is made of concurrent
145143 -- streams we do not reserve the yield limit in the constituent
@@ -149,7 +147,7 @@ workLoopLIFOLimited q st sv winfo = run
149147 yieldLimitOk <- liftIO $ decrementYieldLimit sv
150148 if yieldLimitOk
151149 then do
152− r <- liftIO $ mrun $
150+ r <- liftIO $ runin $
153151 foldStreamShared st yieldk single incrContinue m
154152 res <- restoreM r
155153 case res of
@@ -158,7 +156,7 @@ workLoopLIFOLimited q st sv winfo = run
158156 -- Avoid any side effects, undo the yield limit decrement if we
159157 -- never yielded anything.
160158 else liftIO $ do
161− enqueueLIFO sv q m
159+ enqueueLIFO sv q (RunInIO runin, m)
162160 incrementYieldLimit sv
163161 sendStop sv winfo
164162
@@ -173,9 +171,10 @@ workLoopLIFOLimited q st sv winfo = run
173171 yieldLimitOk <- liftIO $ decrementYieldLimit sv
174172 if res && yieldLimitOk
175173 then foldStreamShared st yieldk single incrContinue r
176− else liftIO $ do
177− incrementYieldLimit sv
178− enqueueLIFO sv q r
174+ else do
175+ runInIO <- captureMonadState
176+ liftIO $ incrementYieldLimit sv
177+ liftIO $ enqueueLIFO sv q (runInIO, r)
179178 return Suspend
180179
181180 dequeue = liftIO $ atomicModifyIORefCAS q $ \case
@@ -191,7 +190,7 @@ workLoopLIFOLimited q st sv winfo = run
191190{-# INLINE workLoopFIFO #-}
192191workLoopFIFO
193192 :: (MonadIO m, MonadBaseControl IO m)
194− => LinkedQueue (Stream m a)
193+ => LinkedQueue (RunInIO m, Stream m a)
195194 -> State Stream m a
196195 -> SVar Stream m a
197196 -> Maybe WorkerInfo
@@ -200,14 +199,13 @@ workLoopFIFO q st sv winfo = run
200199
201200 where
202201
203− mrun = runInIO $ svarMrun sv
202+ stop = liftIO $ sendStop sv winfo
204203 run = do
205204 work <- liftIO $ tryPopR q
206− let stop = liftIO $ sendStop sv winfo
207205 case work of
208206 Nothing -> stop
209− Just m -> do
210− r <- liftIO $ mrun $
207+ Just (RunInIO runin, m) -> do
208+ r <- liftIO $ runin $
211209 foldStreamShared st yieldk single (return Continue) m
212210 res <- restoreM r
213211 case res of
@@ -224,13 +222,14 @@ workLoopFIFO q st sv winfo = run
224222 -- yielding.
225223 yieldk a r = do
226224 res <- liftIO $ sendYield sv winfo (ChildYield a)
227− liftIO $ enqueueFIFO sv q r
225+ runInIO <- captureMonadState
226+ liftIO $ enqueueFIFO sv q (runInIO, r)
228227 return $ if res then Continue else Suspend
229228
230229{-# INLINE workLoopFIFOLimited #-}
231230workLoopFIFOLimited
232− :: (MonadIO m, MonadBaseControl IO m)
233− => LinkedQueue (Stream m a)
231+ :: forall m a. (MonadIO m, MonadBaseControl IO m)
232+ => LinkedQueue (RunInIO m, Stream m a)
234233 -> State Stream m a
235234 -> SVar Stream m a
236235 -> Maybe WorkerInfo
@@ -239,25 +238,24 @@ workLoopFIFOLimited q st sv winfo = run
239238
240239 where
241240
242− mrun = runInIO $ svarMrun sv
241+ stop = liftIO $ sendStop sv winfo
243242 incrContinue = liftIO (incrementYieldLimit sv) >> return Continue
244243 run = do
245244 work <- liftIO $ tryPopR q
246− let stop = liftIO $ sendStop sv winfo
247245 case work of
248246 Nothing -> stop
249− Just m -> do
247+ Just (RunInIO runin, m) -> do
250248 yieldLimitOk <- liftIO $ decrementYieldLimit sv
251249 if yieldLimitOk
252250 then do
253− r <- liftIO $ mrun $
251+ r <- liftIO $ runin $
254252 foldStreamShared st yieldk single incrContinue m
255253 res <- restoreM r
256254 case res of
257255 Continue -> run
258256 Suspend -> stop
259257 else liftIO $ do
260− enqueueFIFO sv q m
258+ enqueueFIFO sv q (RunInIO runin, m)
261259 incrementYieldLimit sv
262260 sendStop sv winfo
263261
@@ -267,7 +265,8 @@ workLoopFIFOLimited q st sv winfo = run
267265
268266 yieldk a r = do
269267 res <- liftIO $ sendYield sv winfo (ChildYield a)
270− liftIO $ enqueueFIFO sv q r
268+ runInIO <- captureMonadState
269+ liftIO $ enqueueFIFO sv q (runInIO, r)
271270 yieldLimitOk <- liftIO $ decrementYieldLimit sv
272271 if res && yieldLimitOk
273272 then return Continue
@@ -292,7 +291,7 @@ getLifoSVar st mrun = do
292291 active <- newIORef 0
293292 wfw <- newIORef False
294293 running <- newIORef S.empty
295− q <- newIORef []
294+ q <- newIORef ([] :: [(RunInIO m, Stream m a)])
296295 yl <- case getYieldLimit st of
297296 Nothing -> return Nothing
298297 Just x -> Just <$> newIORef x
@@ -317,7 +316,7 @@ getLifoSVar st mrun = do
317316 -> (SVar Stream m a -> m [ChildEvent a])
318317 -> (SVar Stream m a -> m Bool)
319318 -> (SVar Stream m a -> IO Bool)
320− -> (IORef [Stream m a]
319+ -> (IORef [(RunInIO m, Stream m a)]
321320 -> State Stream m a
322321 -> SVar Stream m a
323322 -> Maybe WorkerInfo
@@ -414,7 +413,7 @@ getFifoSVar st mrun = do
414413 -> (SVar Stream m a -> m [ChildEvent a])
415414 -> (SVar Stream m a -> m Bool)
416415 -> (SVar Stream m a -> IO Bool)
417− -> (LinkedQueue (Stream m a)
416+ -> (LinkedQueue (RunInIO m, Stream m a)
418417 -> State Stream m a
419418 -> SVar Stream m a
420419 -> Maybe WorkerInfo
@@ -611,7 +610,8 @@ forkSVarAsync style m1 m2 = mkStream $ \st yld sng stp -> do
611610 foldStream st yld sng stp $ fromSVar sv
612611 where
613612 concurrently ma mb = mkStream $ \st yld sng stp -> do
614− liftIO $ enqueue (fromJust $ streamVar st) mb
613+ runInIO <- captureMonadState
614+ liftIO $ enqueue (fromJust $ streamVar st) $ (runInIO, mb)
615615 foldStreamShared st yld sng stp ma
616616
617617{-# INLINE joinStreamVarAsync #-}
@@ -620,7 +620,8 @@ joinStreamVarAsync :: (IsStream t, MonadAsync m)
620620joinStreamVarAsync style m1 m2 = mkStream $ \st yld sng stp ->
621621 case streamVar st of
622622 Just sv | svarStyle sv == style -> do
623− liftIO $ enqueue sv (toStream m2)
623+ runInIO <- captureMonadState
624+ liftIO $ enqueue sv $ (runInIO, toStream m2)
624625 foldStreamShared st yld sng stp m1
625626 _ -> foldStreamShared st yld sng stp (forkSVarAsync style m1 m2)
626627