Socket.readline hangs when encoding is set #942

moritz opened this Issue Mar 7, 2013 · 3 comments

3 participants


In rakudo/rakudo#107 people complain that Rakudo's Socket.get, which calls parrot's Socket.readline, hangs under certain conditions. Removing the code that sets the handle's encoding (UTF-8 by default) fixes the hang, but of course that's not a satisfactory solution (for reasons outline the rakudo pull request).


The code hangs in the recv() call right before

#0  Parrot_io_internal_recv (interp=0x80039ac8, os_handle=4,
    buf=0x8446d824 "", len=252) at src/platform/generic/socket.c:695
#1  0x6ddfe95d in io_socket_read_b (interp=0x80039ac8, handle=0x8444400c,
    buffer=0x8446d824 "", byte_length=252) at src/io/socket.c:266
#2  0x6ddfca1d in Parrot_io_buffer_fill (interp=0x80039ac8, buffer=0x84464de0,
    handle=0x8444400c, vtable=0x800ef738) at src/io/buffer.c:618
#3  0x6de0291c in io_readline_encoded_string (interp=0x80039ac8,
    handle=0x8444400c, vtable=0x800ef738, buffer=0x84464de0,
    encoding=0x6df32940, rs=0x815acbd0) at src/io/utilities.c:425
#4  0x6ddf9161 in Parrot_io_readline_s (interp=0x80039ac8, handle=0x8444400c,
    terminator=0x815acbd0) at src/io/api.c:977

I used the following 2 scripts to reproduce the issue:


    use v6;
    augment class IO::Socket::INET {
        method readline {
            my Mu $PIO  := nqp::getattr(self, $?CLASS, '$!PIO');
    my $socket =
    while $_ = $socket.readline {

    use v6;
    my $socket =<>, :port(1234));
@gerdr gerdr added a commit to gerdr/parrot that referenced this issue Mar 10, 2013
@gerdr gerdr [BUGFIX] Fix issue #942
io_readline_encoded_string() used to wait for max_bytes_per_codepoint
bytes, which is 4 in case of UTF-8.

However, as UTF-8 is variable-length, there's no guarantee that we'll actually
receive that many bytes and we might hang until the stream gets closed.
Parrot Virtual Machine member

Can this issue be closed?


No. The fix that was merged regressed other stuff and has been reverted: While it did fix alway waiting for the maximal length of bytes in case of variable-length codings (and thus potentially blocking indefinitely), it ended up reading not enough in other cases.

The (imo) proper fix turned out to be more involved as I folded the logic into EOF handling. See #944.

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