From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, T_SCC_BODY_TEXT_LINE shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 26D691F87D for ; Thu, 9 Nov 2023 10:09:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1699524588; bh=1cwQRt7JnRnHTD5yawoZsWPvDqP9opXlmNSkY/9ijgE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=NNYShbFVO7Z2tLbyE1/xsrdu93dfj3GZE8DtFYlCRiB/8ye+vsKRh5RVhOK7gy6qS SFGKX1u4Qk1zufsiO3Ul08nCD7sWLBGkVC7D+cG6lHSeSNN0EbVTKUahI2MPTq0B6P jrbDRWA1garzZ7piQ99xKKTsm+avtiOkHn/t3Km8= From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 07/13] net: retry on EINTR and check for {quit} flag Date: Thu, 9 Nov 2023 10:09:40 +0000 Message-ID: <20231109100946.1440611-8-e@80x24.org> In-Reply-To: <20231109100946.1440611-1-e@80x24.org> References: <20231109100946.1440611-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: This should allow us to detect shutdown signals in -watch more quickly and not unnecessarily fail on inconsequential signals such as SIGWINCH. --- lib/PublicInbox/NetNNTPSocks.pm | 1 + lib/PublicInbox/NetReader.pm | 53 +++++++++++++++++++++++---------- lib/PublicInbox/Watch.pm | 2 +- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/lib/PublicInbox/NetNNTPSocks.pm b/lib/PublicInbox/NetNNTPSocks.pm index 306dcacb..d27efba1 100644 --- a/lib/PublicInbox/NetNNTPSocks.pm +++ b/lib/PublicInbox/NetNNTPSocks.pm @@ -19,6 +19,7 @@ sub new_socks { } qw(ProxyAddr ProxyPort SocksVersion SocksDebug SocksResolve); no warnings 'uninitialized'; # needed for $SOCKS_ERROR my $ret = Net::NNTP->new(%opt); # calls PublicInbox::NetNNTPSocks::new + return $ret if $ret || $!{EINTR}; $ret // die "errors: \$!=$! SOCKS=", eval('$IO::Socket::Socks::SOCKS_ERROR // ""'), ', SSL=', diff --git a/lib/PublicInbox/NetReader.pm b/lib/PublicInbox/NetReader.pm index 95cf1de8..e3e5d596 100644 --- a/lib/PublicInbox/NetReader.pm +++ b/lib/PublicInbox/NetReader.pm @@ -60,6 +60,7 @@ sub mic_new ($$$$) { my ($self, $mic_arg, $sec, $uri) = @_; my %mic_arg = (%$mic_arg, Keepalive => 1); my $sa = $self->{cfg_opt}->{$sec}->{-proxy_cfg} || $self->{-proxy_cli}; + my ($mic, $s, $t); if ($sa) { # this `require' needed for worker[1..Inf], since socks_args # only got called in worker[0] @@ -68,24 +69,37 @@ sub mic_new ($$$$) { $opt{SocksDebug} = 1 if $mic_arg{Debug}; $opt{ConnectAddr} = delete $mic_arg{Server}; $opt{ConnectPort} = delete $mic_arg{Port}; - my $s = IO::Socket::Socks->new(%opt) or die - "E: <$uri> ".eval('$IO::Socket::Socks::SOCKS_ERROR'); + do { + $! = 0; + $s = IO::Socket::Socks->new(%opt); + } until ($s || !$!{EINTR} || $self->{quit}); + return if $self->{quit}; + $s or die "E: <$uri> ".eval('$IO::Socket::Socks::SOCKS_ERROR'); + $mic_arg{Socket} = $s; if (my $o = delete $mic_arg{Ssl}) { # for imaps:// $o = mic_tls_opt($o, $opt{ConnectAddr}); - $s = IO::Socket::SSL->start_SSL($s, @$o) or die - "E: <$uri> ".(IO::Socket::SSL->errstr // ''); + do { + $! = 0; + $t = IO::Socket::SSL->start_SSL($s, @$o); + } until ($t || !$!{EINTR} || $self->{quit}); + return if $self->{quit}; + $t or die "E: <$uri> ".(IO::Socket::SSL->errstr // ''); + $mic_arg{Socket} = $t; } elsif ($o = $mic_arg{Starttls}) { # Mail::IMAPClient will use this: $mic_arg{Starttls} = mic_tls_opt($o, $opt{ConnectAddr}); } - $mic_arg{Socket} = $s; } elsif ($mic_arg{Ssl} || $mic_arg{Starttls}) { for my $f (qw(Ssl Starttls)) { my $o = $mic_arg{$f} or next; $mic_arg{$f} = mic_tls_opt($o, $mic_arg{Server}); } } - PublicInbox::IMAPClient->new(%mic_arg); + do { + $! = 0; + $mic = PublicInbox::IMAPClient->new(%mic_arg); + } until ($mic || !$!{EINTR} || $self->{quit}); + $mic; } sub auth_anon_cb { '' }; # for Mail::IMAPClient::Authcallback @@ -152,6 +166,7 @@ sub mic_for ($$$$) { # mic = Mail::IMAPClient }; require PublicInbox::IMAPClient; my $mic = mic_new($self, $mic_arg, $sec, $uri); + return if $self->{quit}; ($mic && $mic->IsConnected) or die "E: <$uri> new: $@".onion_hint($lei, $uri); @@ -202,16 +217,20 @@ sub mic_for ($$$$) { # mic = Mail::IMAPClient $mic; } -sub nn_new ($$$) { - my ($nn_arg, $nntp_cfg, $uri) = @_; +sub nn_new ($$$$) { + my ($self, $nn_arg, $nntp_cfg, $uri) = @_; my $nn; + my ($Net_NNTP, $new) = qw(Net::NNTP new); if (defined $nn_arg->{ProxyAddr}) { require PublicInbox::NetNNTPSocks; + ($Net_NNTP, $new) = qw(PublicInbox::NetNNTPSocks new_socks); $nn_arg->{SocksDebug} = 1 if $nn_arg->{Debug}; - $nn = PublicInbox::NetNNTPSocks->new_socks(%$nn_arg) or return; - } else { - $nn = Net::NNTP->new(%$nn_arg) or return; } + do { + $! = 0; + $nn = $Net_NNTP->$new(%$nn_arg); + } until ($nn || !$!{EINTR} || $self->{quit}); + $nn // return; setsockopt($nn, Socket::SOL_SOCKET(), Socket::SO_KEEPALIVE(), 1); # default to using STARTTLS if it's available, but allow @@ -268,8 +287,9 @@ sub nn_for ($$$$) { # nn = Net::NNTP $nn_arg->{SSL} = 1 if $uri->secure; # snews == nntps my $sa = $self->{-proxy_cli}; %$nn_arg = (%$nn_arg, %$sa) if $sa; - my $nn = nn_new($nn_arg, $nntp_cfg, $uri) or - die "E: <$uri> new: $@".onion_hint($lei, $uri); + my $nn = nn_new($self, $nn_arg, $nntp_cfg, $uri); + return if $self->{quit}; + $nn // die "E: <$uri> new: $@".onion_hint($lei, $uri); if ($cred) { $cred->fill($lei) unless defined($p); # may prompt user here if ($nn->authinfo($u, $p)) { @@ -382,8 +402,9 @@ sub imap_common_init ($;$) { my $sec = uri_section($orig_uri); my $uri = PublicInbox::URIimap->new("$sec/"); my $mic = $mics->{$sec} //= - mic_for($self, $uri, $mic_common, $lei) // - die "Unable to continue\n"; + mic_for($self, $uri, $mic_common, $lei); + return if $self->{quit}; + $mic // die "Unable to continue\n"; next unless $self->isa('PublicInbox::NetWriter'); next if $self->{-skip_creat}; my $dst = $orig_uri->mailbox // next; @@ -751,7 +772,7 @@ sub nn_get { my $nn_arg = $self->{net_arg}->{$sec} or die "BUG: no Net::NNTP->new arg for $sec"; my $nntp_cfg = $self->{cfg_opt}->{$sec}; - $nn = nn_new($nn_arg, $nntp_cfg, $uri) or return; + $nn = nn_new($self, $nn_arg, $nntp_cfg, $uri) or return; if (my $postconn = $nntp_cfg->{-postconn}) { for my $m_arg (@$postconn) { my ($method, @args) = @$m_arg; diff --git a/lib/PublicInbox/Watch.pm b/lib/PublicInbox/Watch.pm index c2b1312a..1cdf12a5 100644 --- a/lib/PublicInbox/Watch.pm +++ b/lib/PublicInbox/Watch.pm @@ -494,7 +494,7 @@ sub poll_fetch_reap { # awaitpid callback sub watch_imap_init ($$) { my ($self, $poll) = @_; - my $mics = PublicInbox::NetReader::imap_common_init($self); + my $mics = PublicInbox::NetReader::imap_common_init($self) or return; my $idle = []; # [ uri1, intvl1, uri2, intvl2 ] for my $uri (@{$self->{imap_order}}) { my $sec = uri_section($uri);