From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 14/30] ds: introduce and use do_fork helper
Date: Tue, 17 Oct 2023 23:37:59 +0000 [thread overview]
Message-ID: <20231017233815.1637932-15-e@80x24.org> (raw)
In-Reply-To: <20231017233815.1637932-1-e@80x24.org>
This ensures we handle RNG reseeding and resetting the event
loop properly in child processes after forking.
---
lib/PublicInbox/DS.pm | 12 ++++++++++++
lib/PublicInbox/Daemon.pm | 16 +++++-----------
lib/PublicInbox/IPC.pm | 12 ++----------
lib/PublicInbox/TestCommon.pm | 3 +--
lib/PublicInbox/Watch.pm | 11 ++---------
lib/PublicInbox/Xapcmd.pm | 5 ++---
6 files changed, 24 insertions(+), 35 deletions(-)
diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index eefbdcc3..9960937d 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -34,6 +34,7 @@ use PublicInbox::Tmpfile;
use PublicInbox::Select;
use Errno qw(EAGAIN EINVAL ECHILD);
use Carp qw(carp croak);
+use autodie qw(fork);
our @EXPORT_OK = qw(now msg_more awaitpid add_timer add_uniq_timer);
my $nextq; # queue for next_tick
@@ -737,6 +738,17 @@ sub awaitpid {
}
}
+sub do_fork () {
+ my $seed = rand(0xffffffff);
+ my $pid = fork;
+ if ($pid == 0) {
+ srand($seed);
+ eval { Net::SSLeay::randomize() };
+ Reset();
+ }
+ $pid;
+}
+
package PublicInbox::DummyPoller; # only used during Reset
use v5.12;
diff --git a/lib/PublicInbox/Daemon.pm b/lib/PublicInbox/Daemon.pm
index 520cef72..f33f6f17 100644
--- a/lib/PublicInbox/Daemon.pm
+++ b/lib/PublicInbox/Daemon.pm
@@ -541,17 +541,11 @@ sub reap_worker { # awaitpid CB
sub start_worker ($) {
my ($nr) = @_;
- my $seed = rand(0xffffffff);
return unless @listeners;
- my $pid = fork;
- if (!defined($pid)) {
- warn "fork: $!";
- } elsif ($pid == 0) {
+ my $pid = PublicInbox::DS::do_fork;
+ if ($pid == 0) {
undef %WORKERS;
- PublicInbox::DS::Reset();
local $PublicInbox::DS::Poller; # allow epoll/kqueue
- srand($seed);
- eval { Net::SSLeay::randomize() };
$set_user->() if $set_user;
PublicInbox::EOFpipe->new($parent_pipe, \&worker_quit);
worker_loop();
@@ -563,9 +557,9 @@ sub start_worker ($) {
}
sub start_workers {
- for my $nr (grep { !defined($WORKERS{$_}) } (0..($nworker - 1))) {
- start_worker($nr);
- }
+ my @idx = grep { !defined($WORKERS{$_}) } (0..($nworker - 1)) or return;
+ eval { start_worker($_) for @idx };
+ warn "E: $@\n" if $@;
}
sub trim_workers {
diff --git a/lib/PublicInbox/IPC.pm b/lib/PublicInbox/IPC.pm
index 5964645e..3292d960 100644
--- a/lib/PublicInbox/IPC.pm
+++ b/lib/PublicInbox/IPC.pm
@@ -102,12 +102,8 @@ sub ipc_worker_spawn {
pipe(my $r_res, my $w_res);
my $sigset = $oldset // PublicInbox::DS::block_signals();
$self->ipc_atfork_prepare;
- my $seed = rand(0xffffffff);
- my $pid = fork;
+ my $pid = PublicInbox::DS::do_fork;
if ($pid == 0) {
- srand($seed);
- eval { Net::SSLeay::randomize() };
- eval { PublicInbox::DS->Reset };
delete @$self{qw(-wq_s1 -wq_s2 -wq_workers -wq_ppid)};
$w_req = $r_res = undef;
$w_res->autoflush(1);
@@ -341,13 +337,9 @@ sub _wq_worker_start {
my ($self, $oldset, $fields, $one, @cb_args) = @_;
my ($bcast1, $bcast2);
$one or socketpair($bcast1, $bcast2, AF_UNIX, SOCK_SEQPACKET, 0);
- my $seed = rand(0xffffffff);
- my $pid = fork;
+ my $pid = PublicInbox::DS::do_fork;
if ($pid == 0) {
- srand($seed);
- eval { Net::SSLeay::randomize() };
undef $bcast1;
- eval { PublicInbox::DS->Reset };
delete @$self{qw(-wq_s1 -wq_ppid)};
$self->{-wq_worker_nr} =
keys %{delete($self->{-wq_workers}) // {}};
diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm
index 323152b4..77da822b 100644
--- a/lib/PublicInbox/TestCommon.pm
+++ b/lib/PublicInbox/TestCommon.pm
@@ -549,9 +549,8 @@ sub start_script {
require PublicInbox::OnDestroy;
my $tmp_mask = PublicInbox::OnDestroy->new(
\&PublicInbox::DS::sig_setmask, $oset);
- my $pid = fork // die "fork: $!";
+ my $pid = PublicInbox::DS::do_fork();
if ($pid == 0) {
- eval { PublicInbox::DS->Reset };
for (@{delete($opt->{-CLOFORK}) // []}) {
close($_) or die "close $!";
}
diff --git a/lib/PublicInbox/Watch.pm b/lib/PublicInbox/Watch.pm
index 3426d4a7..41b77dc1 100644
--- a/lib/PublicInbox/Watch.pm
+++ b/lib/PublicInbox/Watch.pm
@@ -385,7 +385,6 @@ sub watch_atfork_child ($) {
my ($self) = @_;
delete $self->{pids};
delete $self->{opendirs};
- PublicInbox::DS->Reset;
my $sig = delete $self->{sig};
$sig->{CHLD} = $sig->{HUP} = $sig->{USR1} = 'DEFAULT';
# TERM/QUIT/INT call ->quit, which works in both parent+child
@@ -413,11 +412,8 @@ sub imap_idle_reap { # awaitpid callback
sub imap_idle_fork {
my ($self, $uri, $intvl) = @_;
return if $self->{quit};
- my $seed = rand(0xffffffff);
- my $pid = fork // die "fork: $!";
+ my $pid = PublicInbox::DS::do_fork;
if ($pid == 0) {
- srand($seed);
- eval { Net::SSLeay::randomize() };
watch_atfork_child($self);
watch_imap_idle_1($self, $uri, $intvl);
_exit(0);
@@ -477,11 +473,8 @@ sub poll_fetch_fork { # DS::add_timer callback
my @imap = grep { # push() always returns > 0
$_->scheme =~ m!\Aimaps?!i ? 1 : (push(@nntp, $_) < 0)
} @$uris;
- my $seed = rand(0xffffffff);
- my $pid = fork // die "fork: $!";
+ my $pid = PublicInbox::DS::do_fork;
if ($pid == 0) {
- srand($seed);
- eval { Net::SSLeay::randomize() };
watch_atfork_child($self);
watch_imap_fetch_all($self, \@imap) if @imap;
watch_nntp_fetch_all($self, \@nntp) if @nntp;
diff --git a/lib/PublicInbox/Xapcmd.pm b/lib/PublicInbox/Xapcmd.pm
index 4e055acf..c2b66e69 100644
--- a/lib/PublicInbox/Xapcmd.pm
+++ b/lib/PublicInbox/Xapcmd.pm
@@ -11,6 +11,7 @@ use PublicInbox::SearchIdx;
use File::Temp 0.19 (); # ->newdir
use File::Path qw(remove_tree);
use POSIX qw(WNOHANG _exit);
+use PublicInbox::DS;
# support testing with dev versions of Xapian which installs
# commands with a version number suffix (e.g. "xapian-compact-1.5")
@@ -102,10 +103,8 @@ sub commit_changes ($$$$) {
sub cb_spawn {
my ($cb, $args, $opt) = @_; # $cb = cpdb() or compact()
- my $seed = rand(0xffffffff);
- my $pid = fork // die "fork: $!";
+ my $pid = PublicInbox::DS::do_fork;
return $pid if $pid > 0;
- srand($seed);
$SIG{__DIE__} = sub { warn @_; _exit(1) }; # don't jump up stack
$cb->($args, $opt);
_exit(0);
next prev parent reply other threads:[~2023-10-17 23:38 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-17 23:37 [PATCH 00/30] autodie-ification and code simplifications Eric Wong
2023-10-17 23:37 ` [PATCH 01/30] lei_mirror: start converting to autodie Eric Wong
2023-10-17 23:37 ` [PATCH 02/30] lei_mirror: autodie most `close' calls Eric Wong
2023-10-17 23:37 ` [PATCH 03/30] lei_mirror: use autodie for most `open' calls Eric Wong
2023-10-17 23:37 ` [PATCH 04/30] git: introduce read_all function Eric Wong
2023-10-17 23:37 ` [PATCH 05/30] import: use read_all to detect short reads Eric Wong
2023-10-17 23:37 ` [PATCH 06/30] lei_mirror: use read_all Eric Wong
2023-10-17 23:37 ` [PATCH 07/30] use read_all in more places to improve safety Eric Wong
2023-10-17 23:37 ` [PATCH 08/30] xap_helper*: use autodie in more places Eric Wong
2023-10-17 23:37 ` [PATCH 09/30] xap_helper: die more easily in both implementations Eric Wong
2023-10-17 23:37 ` [PATCH 10/30] xap_helper: simplify SIGTERM exit checks Eric Wong
2023-10-17 23:37 ` [PATCH 11/30] xap_helper: autodie for getsockopt Eric Wong
2023-10-17 23:37 ` [PATCH 12/30] xap_client: autodie for pipe and socketpair Eric Wong
2023-10-17 23:37 ` [PATCH 13/30] xt/git-http-backend: remove Net::HTTP usage Eric Wong
2023-10-17 23:37 ` Eric Wong [this message]
2023-10-17 23:38 ` [PATCH 15/30] ds: get rid of SetLoopTimeout Eric Wong
2023-10-17 23:38 ` [PATCH 16/30] cindex: drop some unused functions Eric Wong
2023-10-17 23:38 ` [PATCH 17/30] syscall: common $F_SETPIPE_SZ definition Eric Wong
2023-10-17 23:38 ` [PATCH 18/30] t/lei-up: additional diagnostics for match failures Eric Wong
2023-10-17 23:38 ` [PATCH 19/30] test_common: use autodie and read_all where possible Eric Wong
2023-10-17 23:38 ` [PATCH 20/30] test_common: only hide TCP port in messages Eric Wong
2023-10-17 23:38 ` [PATCH 21/30] test_common: use $cwdfh for every run_script command Eric Wong
2023-10-17 23:38 ` [PATCH 22/30] init: drop extraneous `+' Eric Wong
2023-10-17 23:38 ` [PATCH 23/30] init: use autodie to reduce distractions Eric Wong
2023-10-17 23:38 ` [PATCH 24/30] xt/mem-imapd-tls: remove unused/broken epoll imports Eric Wong
2023-10-17 23:38 ` [PATCH 25/30] xt/mem-imapd-tls: reduce FDs for lsof use Eric Wong
2023-10-17 23:38 ` [PATCH 26/30] lei: use autodie where appropriate Eric Wong
2023-10-17 23:38 ` [PATCH 27/30] lei_auth: update comments and use v5.12 Eric Wong
2023-10-17 23:38 ` [PATCH 28/30] lei_config: drop redundant open check Eric Wong
2023-10-17 23:38 ` [PATCH 29/30] convert: use read_all to simplify error checks Eric Wong
2023-10-17 23:38 ` [PATCH 30/30] idx_stack: use autodie + read_all Eric Wong
2023-10-19 1:14 ` [PATCH 31/30] lei: simplify startq/au_done wakeup notifications 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=20231017233815.1637932-15-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.
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).