Skip to content

Instantly share code, notes, and snippets.

@pmichaud
Created September 28, 2012 06:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmichaud/3798179 to your computer and use it in GitHub Desktop.
Save pmichaud/3798179 to your computer and use it in GitHub Desktop.
We need to decide (quickly!) how to handle IO buffering for the
2012.09 Star release, as the 2012.09 compiler release introduces
several very user-visible regressions with standard filehandle IO.
Apparently Parrot versions prior to 4.8.0 have opened the
standard output filehandle as unbuffered, at least when
the standard output is an interactive device. A simple
test program illustrates this:
.sub 'main' :main
print "abc "
sleep 2
print "def\n"
sleep 2
.end
In Parrot versions prior to 4.8.0 (going back through at least 2.0.0),
running the above program immediately displays "abc ", waits 2 seconds,
display "def\n", waits 2 more seconds, then exits.
Starting with Parrot 4.8.0, the standard output appears to be
line buffered, so that running the above program waits 2 seconds,
displays "abc def\n", waits 2 more seconds, then exits.
Parrot new buffering behavior therefore has an impact on interactive
prompting; e.g., when a program displays a prompt and then waits
for input:
.sub 'main' :main
print "abc "
$P0 = getstdin
$S0 = $P0.'readline'()
print "def\n"
.end
Prior to 4.8.0, the "abc " prompt would be unbuffered and hence
displayed immediately, before the problem blocks waiting for an
input line. In 4.8.0 the "abc " prompt is buffered and not
displayed, such that a user doesn't see the "abc " prompt until
_after_ a line of input is entered. This has been entered as
Parrot issue #847. A "fix" has been added to Parrot HEAD that
flushes the standard output whenever the readline method is
called on any filehandle... but that's not exactly right either.
So far I've looked primarily at standard input and output, I
don't know if Parrot has changed the default buffering
characteristics for other filehandles or streams (in ways that
would create further regressions).
No matter how we look at it, the buffering behavior of Parrot
4.8.0 and Rakudo 2012.09 as they stand now contain unacceptable
regressions that we have to address before making a 2012.09 Star
release. I have several ideas below; most of them aren't intended
as permanent solutions, but are rather band-aids that give us space
of a few releases to warn users of upcoming changes to IO buffering
and bring them in gradually.
(a) Create a 2012.09.1 Rakudo release that forces $*OUT to be
unbuffered. This might still leave regressions for programs
that open standard output directly, or for other filehandles
that Parrot had unbuffered by default but now buffers.
(b) Investigate how buffering was handled for various filehandle
types in previous versions of Rakudo, and create a 2012.09.1
release that explicitly forces those settings regardless of
Parrot's defaults.
(c) See if we can get a transition plan implemented in Parrot
and a quick "bugfix release" that can be used for a 2012.09.1
release.
(d) Release a 2012.09.1 that goes back to using 4.6.0 as the
base Parrot release. This would mean reverting a fair number
of I/O-related changes (and possibly others) that have been made
since the 2012.08 release.
(e) Release the 2012.09 Star compiler based on the 2012.08 compiler
release (and hence Parrot 4.6.0). This would means Star 2012.09
wouldn't contain macros or the recent QAST improvements -- indeed,
it would end up being almost identical to the 2012.08 Star release.
Again, none of the above are intended as the "permanent answer" to
the problem -- they're all in the nature of migrating the solution
over several Star releases and avoiding sharp regressions in the 2012.09
release.
There have also been other I/O-related issues reported with 4.8.0;
in particular where users have to send EOF (^D on unix systems, ^Z on
windows) before any keyboard input is recognized. I haven't been able
to duplicate this on my platforms yet, I'm hoping someone can golf
a simple test case or two to show where things are failing now but
worked previously.
Any suggestions or comments for the above would be greatly appreciated.
Pm
@felher
Copy link

felher commented Sep 28, 2012

Hey folks.

On one of my machines with 2012.08 $*IN.get() works as intended:

0 0 felher@fasel [ ~/testrakudo ] %> ./perl6 -e 'say $_IN.get();'
abcd
abcd
0 0 felher@fasel [ ~/testrakudo ] %> ./perl6 -e 'say $_IN.get;'
adsf
adsf
0 0 felher@fasel [ ~/testrakudo ] %>

After entering one line, it gets read in and printed without me having to press ^D.
With latest git rakudo on the other hand:

0 0 felher@fasel [ ~/testrakudo ] %> ./perl6 -e 'say $_IN.get;'
abcd
abcd
0 0 felher@fasel [ ~/testrakudo ] %> ./perl6 -e 'say $_IN.get();'
abcd
efgh
ijkl
mnop
qrst
uvwx
abcd
efgh
ijkl
mnop
qrst
uvwx
^D
0 0 felher@fasel [ ~/testrakudo ] %>

this is reproducible on my machine. Even the difference between $IN.get() and $*IN.get is. Every longer code example (well, i didn't try them all ;) ) produces the wrong behavior, whether or not i put the () behind it.

Also, i dont know if this helps, but i find this curious too:
0 0 felher@fasel [ ~/testrakudo ] %> ./perl6 readline.pl
-6628616020790442159%
0 0 felher@fasel [ ~/testrakudo ] %> ./perl6 readline.pl
cuid_48_1348827718.59497_nfa%
0 0 felher@fasel [ ~/testrakudo ] %> cat readline.pl
use v6;

Q:PIR {
$P0 = getstdin
$P1 = $P0."record_separator"()
print $P1
}
0 0 felher@fasel [ ~/testrakudo ] %>

@felher
Copy link

felher commented Sep 28, 2012

the ^D should of course be after the first uvwx, sorry for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment