From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id BD6101F9F6 for ; Mon, 10 Jun 2019 05:18:47 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 6/9] nntp: use sysread to append to existing buffer Date: Mon, 10 Jun 2019 05:18:43 +0000 Message-Id: <20190610051846.26757-7-e@80x24.org> In-Reply-To: <20190610051846.26757-1-e@80x24.org> References: <20190610051846.26757-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: We already do this in PublicInbox::HTTP, as it's superior to DS::read in this regard. Initially (when I started writing NNTP.pm, I wanted to use Danga::Socket's read buffering and push_back_read (removed in DS) but quickly figured out it wasn't useful at all for dealing with trickling clients. --- lib/PublicInbox/NNTP.pm | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index 7729399a..5e66d077 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -954,13 +954,20 @@ sub event_write { sub event_read { my ($self) = @_; use constant LINE_MAX => 512; # RFC 977 section 2.3 - - if (index($self->{rbuf}, "\n") < 0) { - my $buf = $self->read(LINE_MAX) or return $self->close; - $self->{rbuf} .= $$buf; + my $rbuf = \($self->{rbuf}); + my $r; + + if (index($$rbuf, "\n") < 0) { + my $off = length($$rbuf); + $r = sysread($self->{sock}, $$rbuf, LINE_MAX, $off); + unless (defined $r) { + return if $!{EAGAIN}; + return $self->close; + } + return $self->close if $r == 0; } - my $r = 1; - while ($r > 0 && $self->{rbuf} =~ s/\A[ \t\r\n]*([^\r\n]*)\r?\n//) { + $r = 1; + while ($r > 0 && $$rbuf =~ s/\A[ \t\r\n]*([^\r\n]*)\r?\n//) { my $line = $1; return $self->close if $line =~ /[[:cntrl:]]/s; my $t0 = now(); @@ -972,7 +979,7 @@ sub event_read { } return $self->close if $r < 0; - my $len = length($self->{rbuf}); + my $len = length($$rbuf); return $self->close if ($len >= LINE_MAX); update_idle_time($self); } -- EW