Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket.readline hangs when encoding is set #942

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

Socket.readline hangs when encoding is set #942

moritz opened this issue Mar 7, 2013 · 3 comments

Comments

@moritz
Copy link
Contributor

moritz commented Mar 7, 2013

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
Copy link
Contributor

gerdr commented Mar 10, 2013

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 added a commit to gerdr/parrot that referenced this issue Mar 10, 2013
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.
zhuomingliang pushed a commit that referenced this issue Mar 12, 2013
@leto
Copy link
Member

leto commented Mar 25, 2013

Can this issue be closed?

@gerdr
Copy link
Contributor

gerdr commented Mar 25, 2013

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants