@@ -87,7 +87,6 @@ module Node.Stream.Aff
8787import Prelude
8888
8989import Control.Monad.ST.Class (liftST )
90- import Control.Monad.ST.Ref as ST.Ref
9190import Data.Array as Array
9291import Data.Array.ST as Array.ST
9392import Data.Either (Either (..))
@@ -98,6 +97,7 @@ import Effect.Aff (effectCanceler, makeAff, nonCanceler)
9897import Effect.Aff.Class (class MonadAff , liftAff )
9998import Effect.Class (class MonadEffect , liftEffect )
10099import Effect.Exception (catchException )
100+ import Effect.Ref as Ref
101101import Node.Buffer (Buffer )
102102import Node.Buffer as Buffer
103103import Node.Encoding as Encoding
@@ -110,7 +110,6 @@ import Node.Stream.Aff.Internal (onceDrain, onceEnd, onceError, onceReadable, re
110110-- |
111111-- | This function is useful for streams like __stdin__ which never
112112-- | reach End-Of-File.
113- -- |
114113readSome
115114 :: forall m r
116115 . MonadAff m
@@ -121,6 +120,11 @@ readSome r = liftAff <<< makeAff $ \res -> do
121120
122121 removeError <- onceError r $ res <<< Left
123122
123+ removeEnd <- onceEnd r do
124+ removeError
125+ ret <- liftST $ Array.ST .unsafeFreeze bufs
126+ res (Right (Tuple ret false ))
127+
124128 -- try to read right away.
125129 catchException (res <<< Left ) do
126130 ifM (readable r)
@@ -133,15 +137,19 @@ readSome r = liftAff <<< makeAff $ \res -> do
133137 pure false
134138 do
135139 removeError
140+ removeEnd
136141 res (Right (Tuple [] false ))
137142
138143
139144 ret1 <- liftST $ Array.ST .unsafeFreeze bufs
140- removeReadable <- if Array .length ret1 == 0 then do
141- -- if we couldn't read anything right away, then wait until the stream is readable.
145+ readagain <- readable r
146+ removeReadable <- if readagain && Array .length ret1 == 0 then do
147+ -- if still readable and we couldn't read anything right away,
148+ -- then wait for the readable event.
142149 -- “The 'readable' event will also be emitted once the end of the
143150 -- stream data has been reached but before the 'end' event is emitted.”
144- -- We already checked the `readable` property so we don't have to check again.
151+ -- if not readable then this was a zero-length Readable stream.
152+ -- https://nodejs.org/api/stream.html#event-readable
145153 onceReadable r do
146154 catchException (res <<< Left ) do
147155 untilE do
@@ -152,23 +160,24 @@ readSome r = liftAff <<< makeAff $ \res -> do
152160 pure false
153161 ret2 <- liftST $ Array.ST .unsafeFreeze bufs
154162 removeError
155- readagain <- readable r
156- res (Right (Tuple ret2 readagain))
163+ removeEnd
164+ readagain2 <- readable r
165+ res (Right (Tuple ret2 readagain2))
157166
158167 -- return what we read right away
159168 else do
160169 removeError
161- readagain <- readable r
170+ removeEnd
162171 res (Right (Tuple ret1 readagain))
163172 pure (pure unit) -- dummy canceller
164173
165174 -- canceller might by called while waiting for `onceReadable`
166175 pure $ effectCanceler do
167176 removeError
177+ removeEnd
168178 removeReadable
169179
170180
171-
172181-- | Read all data until the end of the stream.
173182-- |
174183-- | Note that __stdin__ will never end.
@@ -179,7 +188,7 @@ readAll
179188 -> m (Tuple (Array Buffer ) Boolean )
180189readAll r = liftAff <<< makeAff $ \res -> do
181190 bufs <- liftST $ Array.ST .new
182- removeReadable <- liftST $ ST. Ref .new (pure unit :: Effect Unit )
191+ removeReadable <- Ref .new (pure unit :: Effect Unit )
183192
184193 removeError <- onceError r $ res <<< Left
185194
@@ -192,7 +201,7 @@ readAll r = liftAff <<< makeAff $ \res -> do
192201 cleanupRethrow err = do
193202 removeError
194203 removeEnd
195- join $ liftST $ ST. Ref .read removeReadable
204+ join $ Ref .read removeReadable
196205 res (Left err)
197206
198207 -- try to read right away.
@@ -224,15 +233,15 @@ readAll r = liftAff <<< makeAff $ \res -> do
224233 _ <- liftST $ Array.ST .push chunk bufs
225234 pure false
226235 waitToRead -- this is not recursion
227- void $ liftST $ ST. Ref .write removeReadable' removeReadable
236+ Ref .write removeReadable' removeReadable
228237
229238 waitToRead
230239
231240 -- canceller might by called while waiting for `onceReadable`
232241 pure $ effectCanceler do
233242 removeError
234243 removeEnd
235- join $ liftST $ ST. Ref .read removeReadable
244+ join $ Ref .read removeReadable
236245
237246
238247-- | Wait for *N* bytes to become available from the stream.
@@ -249,9 +258,9 @@ readN
249258 -> Int
250259 -> m (Tuple (Array Buffer ) Boolean )
251260readN r n = liftAff <<< makeAff $ \res -> do
252- redRef <- liftST $ ST. Ref .new 0
261+ redRef <- Ref .new 0
253262 bufs <- liftST $ Array.ST .new
254- removeReadable <- liftST $ ST. Ref .new (pure unit :: Effect Unit )
263+ removeReadable <- Ref .new (pure unit :: Effect Unit )
255264
256265 -- TODO on error, we're not calling removeEnd...
257266 removeError <- onceError r $ res <<< Left
@@ -260,22 +269,21 @@ readN r n = liftAff <<< makeAff $ \res -> do
260269 -- if there are more bytes in the stream?
261270 removeEnd <- onceEnd r do
262271 removeError
263- -- join $ liftST $ ST.Ref.read removeReadable
264272 ret <- liftST $ Array.ST .unsafeFreeze bufs
265273 res (Right (Tuple ret false ))
266274
267275 let
268276 cleanupRethrow err = do
269277 removeError
270278 removeEnd
271- join $ liftST $ ST. Ref .read removeReadable
279+ join $ Ref .read removeReadable
272280 res (Left err)
273281
274282 -- try to read N bytes and then either return N bytes or run a continuation
275283 tryToRead continuation = do
276284 catchException cleanupRethrow do
277285 untilE do
278- red <- liftST $ ST. Ref .read redRef
286+ red <- Ref .read redRef
279287 -- https://nodejs.org/docs/latest-v15.x/api/stream.html#stream_readable_read_size
280288 -- “If size bytes are not available to be read, null will be returned
281289 -- unless the stream has ended, in which case all of the data remaining
@@ -285,12 +293,12 @@ readN r n = liftAff <<< makeAff $ \res -> do
285293 Just chunk -> do
286294 _ <- liftST $ Array.ST .push chunk bufs
287295 s <- Buffer .size chunk
288- red' <- liftST $ ST. Ref .modify (_+s) redRef
296+ red' <- Ref .modify (_+s) redRef
289297 if red' >= n then
290298 pure true
291299 else
292300 pure false
293- red <- liftST $ ST. Ref .read redRef
301+ red <- Ref .read redRef
294302 if red >= n then do
295303 removeError
296304 removeEnd
@@ -314,14 +322,14 @@ readN r n = liftAff <<< makeAff $ \res -> do
314322 waitToRead _ = do
315323 removeReadable' <- onceReadable r do
316324 tryToRead waitToRead
317- void $ liftST $ ST. Ref .write removeReadable' removeReadable
325+ Ref .write removeReadable' removeReadable
318326 waitToRead unit
319327
320328 -- canceller might by called while waiting for `onceReadable`
321329 pure $ effectCanceler do
322330 removeError
323331 removeEnd
324- join $ liftST $ ST. Ref .read removeReadable
332+ join $ Ref .read removeReadable
325333
326334
327335-- | Write to a stream.
@@ -335,7 +343,7 @@ write
335343 -> m Unit
336344write w bs = liftAff <<< makeAff $ \res -> do
337345 bufs <- liftST $ Array.ST .thaw bs
338- removeDrain <- liftST $ ST. Ref .new (pure unit :: Effect Unit )
346+ removeDrain <- Ref .new (pure unit :: Effect Unit )
339347
340348 removeError <- onceError w $ res <<< Left
341349
@@ -366,15 +374,15 @@ write w bs = liftAff <<< makeAff $ \res -> do
366374 pure false
367375 else do
368376 removeDrain' <- onceDrain w oneWrite
369- void $ liftST $ ST. Ref .write removeDrain' removeDrain
377+ void $ Ref .write removeDrain' removeDrain
370378 pure true
371379
372380 oneWrite
373381
374382 -- canceller might be called while waiting for `onceDrain`
375383 pure $ effectCanceler do
376384 removeError
377- join $ liftST $ ST. Ref .read removeDrain
385+ join $ Ref .read removeDrain
378386
379387-- | Signal that no more data will be written to the `Writable`. Will complete
380388-- | after all data is written and flushed.
0 commit comments