From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 01/57] ds: get rid of {closed} field
Date: Mon, 24 Jun 2019 02:52:02 +0000 [thread overview]
Message-ID: <20190624025258.25592-2-e@80x24.org> (raw)
In-Reply-To: <20190624025258.25592-1-e@80x24.org>
Merely checking the presence of the {sock} field is
enough, and having multiple sources of truth increases
confusion and the likelyhood of bugs.
---
lib/PublicInbox/DS.pm | 52 ++++++++++++----------------------
lib/PublicInbox/HTTP.pm | 8 +++---
lib/PublicInbox/HTTPD/Async.pm | 2 +-
lib/PublicInbox/NNTP.pm | 30 +++++++++-----------
4 files changed, 37 insertions(+), 55 deletions(-)
diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index 2b04886a..f4fe8793 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -28,7 +28,6 @@ use PublicInbox::Syscall qw(:epoll);
use fields ('sock', # underlying socket
'wbuf', # arrayref of scalars, scalarrefs, or coderefs to write
'wbuf_off', # offset into first element of wbuf to start writing at
- 'closed', # bool: socket is closed
'event_watch', # bitmask of events the client is interested in (POLLIN,OUT,etc.)
);
@@ -366,7 +365,7 @@ sub PostEventLoop {
$sock->close;
# and now we can finally remove the fd from the map. see
- # comment above in _cleanup.
+ # comment above in ->close.
delete $DescriptorMap{$fd};
}
@@ -411,7 +410,6 @@ sub new {
$self->{wbuf} = [];
$self->{wbuf_off} = 0;
- $self->{closed} = 0;
my $ev = $self->{event_watch} = POLLERR|POLLHUP|POLLNVAL;
@@ -457,28 +455,8 @@ Close the socket.
=cut
sub close {
- my PublicInbox::DS $self = $_[0];
- return if $self->{closed};
-
- # this does most of the work of closing us
- $self->_cleanup();
-
- # defer closing the actual socket until the event loop is done
- # processing this round of events. (otherwise we might reuse fds)
- if (my $sock = delete $self->{sock}) {
- push @ToClose, $sock;
- }
-
- return 0;
-}
-
-### METHOD: _cleanup()
-### Called by our closers so we can clean internal data structures.
-sub _cleanup {
- my PublicInbox::DS $self = $_[0];
-
- # we're effectively closed; we have no fd and sock when we leave here
- $self->{closed} = 1;
+ my ($self) = @_;
+ my $sock = delete $self->{sock} or return;
# we need to flush our write buffer, as there may
# be self-referential closures (sub { $client->close })
@@ -487,8 +465,8 @@ sub _cleanup {
# if we're using epoll, we have to remove this from our epoll fd so we stop getting
# notifications about it
- if ($HaveEpoll && $self->{sock}) {
- my $fd = fileno($self->{sock});
+ if ($HaveEpoll) {
+ my $fd = fileno($sock);
epoll_ctl($Epoll, EPOLL_CTL_DEL, $fd, $self->{event_watch}) and
confess("EPOLL_CTL_DEL: $!");
}
@@ -498,9 +476,15 @@ sub _cleanup {
# processing an epoll_wait/etc that returned hundreds of fds, one
# of which is not yet processed and is what we're closing. if we
# keep it in DescriptorMap, then the event harnesses can just
- # looked at $pob->{closed} and ignore it. but if it's an
+ # looked at $pob->{sock} == undef and ignore it. but if it's an
# un-accounted for fd, then it (understandably) freak out a bit
# and emit warnings, thinking their state got off.
+
+ # defer closing the actual socket until the event loop is done
+ # processing this round of events. (otherwise we might reuse fds)
+ push @ToClose, $sock;
+
+ return 0;
}
=head2 C<< $obj->sock() >>
@@ -533,7 +517,7 @@ sub write {
# now-dead object does its second write. that is this case. we
# just lie and say it worked. it'll be dead soon and won't be
# hurt by this lie.
- return 1 if $self->{closed};
+ return 1 unless $self->{sock};
my $bref;
@@ -634,7 +618,7 @@ Turn 'readable' event notification on or off.
=cut
sub watch_read {
my PublicInbox::DS $self = shift;
- return if $self->{closed} || !$self->{sock};
+ my $sock = $self->{sock} or return;
my $val = shift;
my $event = $self->{event_watch};
@@ -642,7 +626,7 @@ sub watch_read {
$event &= ~POLLIN if ! $val;
$event |= POLLIN if $val;
- my $fd = fileno($self->{sock});
+ my $fd = fileno($sock);
# If it changed, set it
if ($event != $self->{event_watch}) {
if ($HaveKQueue) {
@@ -664,14 +648,14 @@ Turn 'writable' event notification on or off.
=cut
sub watch_write {
my PublicInbox::DS $self = shift;
- return if $self->{closed} || !$self->{sock};
+ my $sock = $self->{sock} or return;
my $val = shift;
my $event = $self->{event_watch};
$event &= ~POLLOUT if ! $val;
$event |= POLLOUT if $val;
- my $fd = fileno($self->{sock});
+ my $fd = fileno($sock);
# If it changed, set it
if ($event != $self->{event_watch}) {
@@ -728,7 +712,7 @@ sub as_string {
my PublicInbox::DS $self = shift;
my $rw = "(" . ($self->{event_watch} & POLLIN ? 'R' : '') .
($self->{event_watch} & POLLOUT ? 'W' : '') . ")";
- my $ret = ref($self) . "$rw: " . ($self->{closed} ? "closed" : "open");
+ my $ret = ref($self) . "$rw: " . ($self->{sock} ? 'open' : 'closed');
return $ret;
}
diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm
index 45bf23ec..dff59286 100644
--- a/lib/PublicInbox/HTTP.pm
+++ b/lib/PublicInbox/HTTP.pm
@@ -33,7 +33,7 @@ sub process_pipelineq () {
$pipet = undef;
$pipelineq = [];
foreach (@$q) {
- next if $_->{closed};
+ next unless $_->{sock};
rbuf_process($_);
}
}
@@ -70,7 +70,7 @@ sub event_step { # called by PublicInbox::DS
my $wbuf = $self->{wbuf};
if (@$wbuf) {
$self->write(undef);
- return if $self->{closed} || scalar(@$wbuf);
+ return if !$self->{sock} || scalar(@$wbuf);
}
# only read more requests if we've drained the write buffer,
# otherwise we can be buffering infinitely w/o backpressure
@@ -266,7 +266,7 @@ sub getline_cb ($$$) {
my $buf = eval { $forward->getline };
if (defined $buf) {
$write->($buf); # may close in PublicInbox::DS::write
- unless ($self->{closed}) {
+ if ($self->{sock}) {
my $next = $self->{pull};
if (scalar @{$self->{wbuf}}) {
$self->write($next);
@@ -322,7 +322,7 @@ sub response_write {
use constant MSG_MORE => ($^O eq 'linux') ? 0x8000 : 0;
sub more ($$) {
my $self = $_[0];
- return if $self->{closed};
+ return unless $self->{sock};
if (MSG_MORE && !scalar(@{$self->{wbuf}})) {
my $n = send($self->{sock}, $_[1], MSG_MORE);
if (defined $n) {
diff --git a/lib/PublicInbox/HTTPD/Async.pm b/lib/PublicInbox/HTTPD/Async.pm
index 604627ab..261a01e0 100644
--- a/lib/PublicInbox/HTTPD/Async.pm
+++ b/lib/PublicInbox/HTTPD/Async.pm
@@ -45,7 +45,7 @@ sub main_cb ($$$) {
my $r = sysread($self->{sock}, $$bref, 8192);
if ($r) {
$fh->write($$bref);
- unless ($http->{closed}) { # PublicInbox::DS sets this
+ if ($http->{sock}) { # !closed
if (scalar @{$http->{wbuf}}) {
$self->watch_read(0);
$http->write(restart_read_cb($self));
diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm
index 796ac74d..107cbe31 100644
--- a/lib/PublicInbox/NNTP.pm
+++ b/lib/PublicInbox/NNTP.pm
@@ -57,7 +57,7 @@ sub next_tick () {
# maybe there's more pipelined data, or we'll have
# to register it for socket-readiness notifications
- if (!$nntp->{long_res} && !$nntp->{closed}) {
+ if (!$nntp->{long_res} && $nntp->{sock}) {
check_read($nntp);
}
}
@@ -66,9 +66,8 @@ sub next_tick () {
sub update_idle_time ($) {
my ($self) = @_;
- my $sock = $self->{sock} or return;
- my $fd = fileno($sock);
- defined $fd and $EXPMAP->{$fd} = [ now(), $self ];
+ my $sock = $self->{sock} or return;
+ $EXPMAP->{fileno($sock)} = [ now(), $self ];
}
sub expire_old () {
@@ -134,7 +133,7 @@ sub process_line ($$) {
my $res = eval { $req->($self, @args) };
my $err = $@;
- if ($err && !$self->{closed}) {
+ if ($err && $self->{sock}) {
local $/ = "\n";
chomp($l);
err($self, 'error from: %s (%s)', $l, $err);
@@ -632,7 +631,7 @@ sub long_response ($$) {
my $t0 = now();
$self->{long_res} = sub {
my $more = eval { $cb->() };
- if ($@ || $self->{closed}) {
+ if ($@ || !$self->{sock}) {
$self->{long_res} = undef;
if ($@) {
@@ -640,12 +639,12 @@ sub long_response ($$) {
"%s during long response[$fd] - %0.6f",
$@, now() - $t0);
}
- if ($self->{closed}) {
- out($self, " deferred[$fd] aborted - %0.6f",
- now() - $t0);
- } else {
+ if ($self->{sock}) {
update_idle_time($self);
check_read($self);
+ } else {
+ out($self, " deferred[$fd] aborted - %0.6f",
+ now() - $t0);
}
} elsif ($more) { # scalar @{$self->{wbuf}}:
# no recursion, schedule another call ASAP
@@ -930,7 +929,7 @@ sub more ($$) {
sub do_write ($$) {
my ($self, $data) = @_;
my $done = $self->write($data);
- return 0 if $self->{closed};
+ return 0 unless $self->{sock};
# Do not watch for readability if we have data in the queue,
# instead re-enable watching for readability when we can
@@ -966,13 +965,13 @@ sub do_more ($$) {
sub event_step {
my ($self) = @_;
- return if $self->{closed};
+ return unless $self->{sock};
my $wbuf = $self->{wbuf};
if (@$wbuf) {
update_idle_time($self);
$self->write(undef);
- return if $self->{closed} || scalar(@$wbuf);
+ return if !$self->{sock} || scalar(@$wbuf);
}
return if $self->{long_res};
# only read more requests if we've drained the write buffer,
@@ -1028,9 +1027,8 @@ sub check_read {
sub not_idle_long ($$) {
my ($self, $now) = @_;
- my $sock = $self->{sock} or return;
- defined(my $fd = fileno($sock)) or return;
- my $ary = $EXPMAP->{$fd} or return;
+ my $sock = $self->{sock} or return;
+ my $ary = $EXPMAP->{fileno($sock)} or return;
my $exp_at = $ary->[0] + $EXPTIME;
$exp_at > $now;
}
--
EW
next prev parent reply other threads:[~2019-06-24 2:52 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-24 2:52 [PATCH 00/57] ds: shrink, TLS support, buffer writes to FS Eric Wong
2019-06-24 2:52 ` Eric Wong [this message]
2019-06-24 2:52 ` [PATCH 02/57] ds: get rid of more unused debug instance methods Eric Wong
2019-06-24 2:52 ` [PATCH 03/57] ds: use and export monotonic now() Eric Wong
2019-06-24 2:52 ` [PATCH 04/57] AddTimer: avoid clock_gettime for the '0' case Eric Wong
2019-06-24 2:52 ` [PATCH 05/57] ds: get rid of on_incomplete_write wrapper Eric Wong
2019-06-24 2:52 ` [PATCH 06/57] ds: lazy initialize wbuf_off Eric Wong
2019-06-24 2:52 ` [PATCH 07/57] ds: split out from ->flush_write and ->write Eric Wong
2019-06-24 2:52 ` [PATCH 08/57] ds: lazy-initialize wbuf Eric Wong
2019-06-24 2:52 ` [PATCH 09/57] ds: don't pass `events' arg to EPOLL_CTL_DEL Eric Wong
2019-06-24 2:52 ` [PATCH 10/57] ds: remove support for DS->write(undef) Eric Wong
2019-06-24 2:52 ` [PATCH 11/57] http: favor DS->write(strref) when reasonable Eric Wong
2019-06-24 2:52 ` [PATCH 12/57] ds: share send(..., MSG_MORE) logic Eric Wong
2019-06-24 2:52 ` [PATCH 13/57] ds: switch write buffering to use a tempfile Eric Wong
2019-06-24 2:52 ` [PATCH 14/57] ds: get rid of redundant and unnecessary POLL* constants Eric Wong
2019-06-24 2:52 ` [PATCH 15/57] syscall: get rid of unused EPOLL* constants Eric Wong
2019-06-24 2:52 ` [PATCH 16/57] syscall: get rid of unnecessary uname local vars Eric Wong
2019-06-24 2:52 ` [PATCH 17/57] ds: set event flags directly at initialization Eric Wong
2019-06-24 2:52 ` [PATCH 18/57] ds: import IO::KQueue namespace Eric Wong
2019-06-24 2:52 ` [PATCH 19/57] ds: share watch_chg between watch_read/watch_write Eric Wong
2019-06-24 2:52 ` [PATCH 20/57] ds: remove IO::Poll support (for now) Eric Wong
2019-06-24 2:52 ` [PATCH 21/57] ds: get rid of event_watch field Eric Wong
2019-06-24 2:52 ` [PATCH 22/57] httpd/async: remove EINTR check Eric Wong
2019-06-24 2:52 ` [PATCH 23/57] spawn: remove `Blocking' flag handling Eric Wong
2019-06-24 2:52 ` [PATCH 24/57] qspawn: describe where `$rpipe' come from Eric Wong
2019-06-24 2:52 ` [PATCH 25/57] http|nntp: favor "$! == EFOO" over $!{EFOO} checks Eric Wong
2019-06-24 2:52 ` [PATCH 26/57] ds: favor `delete' over assigning fields to `undef' Eric Wong
2019-06-24 2:52 ` [PATCH 27/57] http: don't pass extra args to PublicInbox::DS::close Eric Wong
2019-06-24 2:52 ` [PATCH 28/57] ds: pass $self to code references Eric Wong
2019-06-24 2:52 ` [PATCH 29/57] evcleanup: replace _run_asap with `event_step' callback Eric Wong
2019-06-24 2:52 ` [PATCH 30/57] ds: remove pointless exit calls Eric Wong
2019-06-24 2:52 ` [PATCH 31/57] http|nntp: be explicit about bytes::length on rbuf Eric Wong
2019-06-24 2:52 ` [PATCH 32/57] ds: hoist out do_read from NNTP and HTTP Eric Wong
2019-06-24 2:52 ` [PATCH 33/57] nntp: simplify re-arming/requeue logic Eric Wong
2019-06-24 2:52 ` [PATCH 34/57] allow use of PerlIO layers for filesystem writes Eric Wong
2019-06-24 2:52 ` [PATCH 35/57] ds: deal better with FS-related errors IO buffers Eric Wong
2019-06-24 2:52 ` [PATCH 36/57] nntp: wait for writability before sending greeting Eric Wong
2019-06-24 2:52 ` [PATCH 37/57] nntp: NNTPS and NNTP+STARTTLS working Eric Wong
2019-06-24 2:52 ` [PATCH 38/57] certs/create-certs.perl: fix cert validity on 32-bit Eric Wong
2019-06-24 2:52 ` [PATCH 39/57] daemon: map inherited sockets to well-known schemes Eric Wong
2019-06-24 2:52 ` [PATCH 40/57] ds|nntp: use CORE::close on socket Eric Wong
2019-06-24 2:52 ` [PATCH 41/57] nntp: call SSL_shutdown in normal cases Eric Wong
2019-06-24 2:52 ` [PATCH 42/57] t/nntpd-tls: slow client connection test Eric Wong
2019-06-24 2:52 ` [PATCH 43/57] daemon: use SSL_MODE_RELEASE_BUFFERS Eric Wong
2019-06-24 2:52 ` [PATCH 44/57] ds: allow ->write callbacks to syswrite directly Eric Wong
2019-06-24 2:52 ` [PATCH 45/57] nntp: reduce allocations for greeting Eric Wong
2019-06-24 2:52 ` [PATCH 46/57] ds: always use EV_ADD with EV_SET Eric Wong
2019-06-24 2:52 ` [PATCH 47/57] nntp: simplify long response logic and fix nesting Eric Wong
2019-06-24 2:52 ` [PATCH 48/57] ds: flush_write runs ->write callbacks even if closed Eric Wong
2019-06-24 2:52 ` [PATCH 49/57] nntp: lazily allocate and stash rbuf Eric Wong
2019-06-24 2:52 ` [PATCH 50/57] ci: require IO::KQueue on FreeBSD, for now Eric Wong
2019-06-24 2:52 ` [PATCH 51/57] nntp: send greeting immediately for plain sockets Eric Wong
2019-06-24 2:52 ` [PATCH 52/57] daemon: set TCP_DEFER_ACCEPT on everything but NNTP Eric Wong
2019-06-24 2:52 ` [PATCH 53/57] daemon: use FreeBSD accept filters on non-NNTP Eric Wong
2019-06-24 2:52 ` [PATCH 54/57] ds: split out IO::KQueue-specific code Eric Wong
2019-06-24 5:24 ` Eric Wong
2019-06-24 2:52 ` [PATCH 55/57] ds: reimplement IO::Poll support to look like epoll Eric Wong
2019-06-24 2:52 ` [PATCH 56/57] Revert "ci: require IO::KQueue on FreeBSD, for now" Eric Wong
2019-06-24 2:52 ` [PATCH 57/57] ds: reduce overhead of tempfile creation Eric Wong
2019-06-24 5:25 ` [PATCH 58/57] Makefile: skip DSKQXS in global syntax check Eric Wong
2019-06-24 18:28 ` [PATCH 59/57] ds: ->write must not clobber empty wbuf array Eric Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://public-inbox.org/README
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190624025258.25592-2-e@80x24.org \
--to=e@80x24.org \
--cc=meta@public-inbox.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/public-inbox.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).