Socket.readline hangs when encoding is set #942

Open
moritz opened this Issue Mar 7, 2013 · 3 comments

3 participants

@moritz

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).

@gerdr

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:

  • server.pl

    use v6;
    use MONKEY_TYPING;
    
    augment class IO::Socket::INET {
        method readline {
            my Mu $PIO  := nqp::getattr(self, $?CLASS, '$!PIO');
            $PIO.encoding(nqp::unbox_s(PARROT_ENCODING(self.encoding)));
            nqp::p6box_s($PIO.readline(nqp::unbox_s($!input-line-separator)));
        }
    }
    
    my $socket = IO::Socket::INET.new(
        :localhost<127.0.0.1>,
        :localport(1234),
        :listen
    ).accept;
    
    while $_ = $socket.readline {
        .perl.say 
    }
    
  • client.pl

    use v6;
    
    my $socket = IO::Socket::INET.new(:host<127.0.0.1>, :port(1234));
    $socket.send("A\n");
    $socket.send("B\n");
    
    $*IN.get;
    
@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.
2dcc1f4
@leto
Parrot Virtual Machine member

Can this issue be closed?

@gerdr

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