2018-04-11 17:02 GMT+02:00 Sven Van Caekenberghe <s...@stfx.eu>:

>
>
> > On 11 Apr 2018, at 16:36, Sven Van Caekenberghe <s...@stfx.eu> wrote:
> >
> > I can make your example, using the Zn variants, work with the following
> change:
> >
> > StdioStream>>#atEnd
> >  ^ peekBuffer isNil or: [ (peekBuffer := self next) isNil ]
>
> Argh, make that
>
> atEnd
>   ^ peekBuffer isNil and: [ (peekBuffer := self next) isNil ]
>

But discussion exactly about "self next isNil": how to avoid it.


>
> but I am still testing, this is probably not the final answer/solution.
>
> > Which is a literal implementation of your statement that you can only
> know that you are atEnd by reading (and thus waiting/blocking) and checking
> for nil, which seems logical to me, given the fact that you *are* waiting
> for user input.
> >
> > BTW, at least on macOS you have to enter ctrl-D (^D) on a separate line,
> I am not sure how relevant that is, but that is probably another argument
> that stdin is special (being line-buffered by the OS, EOF needing to be on
> a separate line).
> >
> > And FWIW, I have been writing networking code in Pharo for years, and I
> have never had issues with unclear semantics of these primitives (#atEnd,
> #next, #peek) on network streams, either the classic SocketStream or the
> Zdc* streams (TLS or not). That is why I think we have to be careful.
> >
> > That being said, it is important to continue this discussion, I find it
> very interesting. I am trying to write some test code using stdin myself,
> to better understand the topic.
> >
> >> On 11 Apr 2018, at 16:06, Alistair Grant <akgrant0...@gmail.com> wrote:
> >>
> >> On 11 April 2018 at 15:11, Sven Van Caekenberghe <s...@stfx.eu> wrote:
> >>>
> >>>
> >>>> On 11 Apr 2018, at 11:12, Sven Van Caekenberghe <s...@stfx.eu> wrote:
> >>>>
> >>>> How does one modify #atEnd to block ? I suppose you are talking about
> StdioStream>>#atEnd ?
> >>>>
> >>>> ^ self peek isNil
> >>>>
> >>>> ?
> >>>
> >>> Still the same question, how do you implement a blocking #atEnd for
> stdin ?
> >>>
> >>> I have seen your stdio.cs which is indeed needed as the current
> StdioStream>>#atEnd is bogus for sure.
> >>>
> >>> But that is still a non-blocking one, right ?
> >>>
> >>> Since there is a peekBuffer in StdioStream, why can't that be used ?
> >>
> >> I think you've created a chicken-and-egg problem with this question,
> >> but ignoring that for now:
> >>
> >>
> >> StdioStream>>peek
> >> "Answer what would be returned if the message next were sent to the
> >> receiver. If the receiver is at the end, answer nil.  "
> >>
> >>   self atEnd ifTrue: [^ nil ].
> >>
> >>   peekBuffer ifNotNil: [ ^ peekBuffer ].
> >>
> >>   ^ peekBuffer := self next.
> >>
> >>
> >>
> >> So when we first start the program, i.e. the user hasn't entered any
> >> input yet, and #peek is called:
> >>
> >> 1. #atEnd returns false because Ctrl-D (or similar) hasn't been
> >> entered (assuming it is non-blocking).
> >> 2. peekBuffer is nil because we haven't previously called #peek.
> >> 3. The system now blocks on "self next".
> >>
> >>
> >> Just a reminder: for terminal input the end-of-file isn't reached
> >> until the user explicitly enters the end of file key (Ctrl-D).
> >>
> >> So, if there is no buffered input (either none has been entered yet,
> >> or all input has been consumed)
> >>
> >> #atEnd (after the patch) calls #primAtEnd:.
> >>
> >> At the moment, #primAtEnd: ends up calling the libc function feof(),
> >> which is non-blocking and answers the end-of-file flag for the FILE*.
> >> Since the user hasn't entered Ctrl-D, that's false.
> >>
> >> If we want to control iteration over the stream and ensure that we
> >> don't need to do a "stream next == nil" check, then #primAtEnd: is
> >> going to have to peek for the next character, and that means waiting
> >> for the user to enter that character.
> >>
> >> In c that is typically done using:
> >>
> >> atEnd = ungetc(fgetc(fp), fp);
> >>
> >> and fgetc() will block until the user enters something.
> >>
> >>> I have run your example testAtEnd.st now, and it works/fails as
> advertised.
> >>
> >> :-)
> >>
> >>
> >> Cheers,
> >> Alistair
> >
>
>
>

Reply via email to