@@ -64,11 +64,13 @@ module Streamly.Internal.Data.Stream.StreamD.Generate
64 , fromProducer
64 , fromProducer
65 , fromSVar
65 , fromSVar
66 , toStreamD
66 , toStreamD
70−import Control.Concurrent (threadDelay)
72+import Control.Concurrent (myThreadId, threadDelay)
71−import Control.Monad (forever)
73+import Control.Monad (void, forever)
72import Control.Monad.IO.Class (MonadIO(..))
74import Control.Monad.IO.Class (MonadIO(..))
73import Data.Int (Int64)
75import Data.Int (Int64)
74import Streamly.Internal.Data.Time.Units
76import Streamly.Internal.Data.Time.Units
@@ -79,6 +81,7 @@ import Streamly.Internal.Data.Time.Units
79import Streamly.Internal.Data.Unfold.Types (Unfold(..))
81import Streamly.Internal.Data.Unfold.Types (Unfold(..))
81import qualified Streamly.Internal.Data.IORef.Prim as Prim
83import qualified Streamly.Internal.Data.IORef.Prim as Prim
84+import qualified Streamly.Internal.Data.Stream.StreamK as K
83import Prelude hiding (iterate, repeat, replicate, takeWhile)
86import Prelude hiding (iterate, repeat, replicate, takeWhile)
84import Streamly.Internal.Data.Stream.StreamD.Type
87import Streamly.Internal.Data.Stream.StreamD.Type
@@ -412,3 +415,27 @@ fromListM = Stream step
412 {-# INLINE_LATE step #-}
415 {-# INLINE_LATE step #-}
413 step _ (m:ms) = m >>= \x -> return $ Yield x ms
416 step _ (m:ms) = m >>= \x -> return $ Yield x ms
414 step _ [] = return Stop
417 step _ [] = return Stop
419+-- Note: we can use another API with two callbacks stop and yield if we want
420+-- the callback to be able to indicate end of stream.
422+-- | Generates a callback and a stream pair. The callback returned is used to
423+-- queue values to the stream. The stream is infinite, there is no way for the
424+-- callback to indicate that it is done now.
428+{-# INLINE_NORMAL newCallbackStream #-}
429+newCallbackStream :: (K.IsStream t, MonadAsync m) => m ((a -> m ()), t m a)
430+newCallbackStream = do
431+ sv <- newParallelVar StopNone defState
433+ -- XXX Add our own thread-id to the SVar as we can not know the callback's
434+ -- thread-id and the callback is not run in a managed worker. We need to
435+ -- handle this better.
436+ liftIO myThreadId >>= modifyThread sv
438+ let callback a = liftIO $ void $ send sv (ChildYield a)
439+ -- XXX we can return an SVar and then the consumer can unfold from the
441+ return (callback, fromStreamD (fromSVar sv))