dumping ground for random patches and texts
 help / color / mirror / Atom feed
From: Eric Wong <e@80x24.org>
To: spew@80x24.org
Subject: [PATCH 05/10] daemon: workaround pre-EVFILT_SIGNAL signals
Date: Sat,  2 Sep 2023 11:09:55 +0000	[thread overview]
Message-ID: <20230902111000.1747604-5-e@80x24.org> (raw)
In-Reply-To: <20230902111000.1747604-1-e@80x24.org>

FreeBSD and OpenBSD kqueue EVFILT_SIGNAL isn't able to handle
blocked signals which were sent before the filter is created.
This behavior differs from Linux signalfd, which can process
blocked signals that were sent before the signalfd existed.
---
 lib/PublicInbox/DS.pm    | 27 ++++++++++++++++++++++++---
 lib/PublicInbox/Sigfd.pm |  3 ++-
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index 97546016..389ca70d 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -28,7 +28,7 @@ use POSIX qw(WNOHANG sigprocmask SIG_SETMASK);
 use Fcntl qw(SEEK_SET :DEFAULT O_APPEND);
 use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
 use Scalar::Util qw(blessed);
-use PublicInbox::Syscall qw(:epoll);
+use PublicInbox::Syscall qw(:epoll %SIGNUM);
 use PublicInbox::Tmpfile;
 use Errno qw(EAGAIN EINVAL ECHILD EINTR);
 use Carp qw(carp croak);
@@ -259,19 +259,40 @@ sub PostEventLoop () {
 			: 1
 }
 
+sub allowset ($) {
+	my ($sig) = @_; # { signame => whatever }
+	my $ret = POSIX::SigSet->new;
+	$ret->fillset or die "fillset: $!";
+	for my $s (keys %$sig) {
+		my $num = $SIGNUM{$s} // POSIX->can("SIG$s")->();
+		$ret->delset($num) or die "delset ($s => $num): $!";
+	}
+	for (@UNBLOCKABLE) { $ret->delset($_) or die "delset($_): $!" }
+	$ret;
+}
+
 # Start processing IO events. In most daemon programs this never exits. See
 # C<post_loop_do> for how to exit the loop.
 sub event_loop (;$$) {
 	my ($sig, $oldset) = @_;
 	$Epoll //= _InitPoller();
 	require PublicInbox::Sigfd if $sig;
-	my $sigfd = PublicInbox::Sigfd->new($sig, 1) if $sig;
+	my $sigfd = $sig ? PublicInbox::Sigfd->new($sig, 1) : undef;
+	if ($sigfd && $sigfd->{is_kq}) {
+		my $tmp = allowset($sig);
+		local @SIG{keys %$sig} = values(%$sig);
+		sig_setmask($tmp, my $old = POSIX::SigSet->new);
+		# Unlike Linux signalfd, EVFILT_SIGNAL can't handle
+		# signals received before the filter is created,
+		# so we peek at signals here.
+		sig_setmask($old);
+	}
 	local @SIG{keys %$sig} = values(%$sig) if $sig && !$sigfd;
 	local $SIG{PIPE} = 'IGNORE';
 	if (!$sigfd && $sig) {
 		# wake up every second to accept signals if we don't
 		# have signalfd or IO::KQueue:
-		sig_setmask($oldset);
+		sig_setmask($oldset // allowset($sig));
 		PublicInbox::DS->SetLoopTimeout(1000);
 	}
 	$_[0] = $sigfd = $sig = undef; # $_[0] == sig
diff --git a/lib/PublicInbox/Sigfd.pm b/lib/PublicInbox/Sigfd.pm
index 3c1d3811..5656baeb 100644
--- a/lib/PublicInbox/Sigfd.pm
+++ b/lib/PublicInbox/Sigfd.pm
@@ -31,8 +31,9 @@ sub new {
 		$self->SUPER::new($io, EPOLLIN | EPOLLET);
 	} else { # master main loop
 		$self->{sock} = $io;
-		$self;
 	}
+	$self->{is_kq} = 1 if tied(*$io);
+	$self;
 }
 
 # PublicInbox::Daemon in master main loop (blocking)

  parent reply	other threads:[~2023-09-02 11:10 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-02 11:09 [PATCH 01/10] ds: don't block important signals we don't use Eric Wong
2023-09-02 11:09 ` [PATCH 02/10] t/sigfd: test EVFILT_SIGNAL vs signalfd differences Eric Wong
2023-09-02 11:09 ` [PATCH 03/10] t/sigfd: better checks related to SIGWINCH Eric Wong
2023-09-02 11:09 ` [PATCH 04/10] update devel/syscall-list to devel/sysdefs-list Eric Wong
2023-09-02 11:09 ` Eric Wong [this message]
2023-09-02 11:09 ` [PATCH 06/10] watch: ensure children can use signal handlers Eric Wong
2023-09-02 11:09 ` [PATCH 07/10] test_common: start_script: block signals around fork Eric Wong
2023-09-02 11:09 ` [PATCH 08/10] xap_helper: support SIGTTIN+SIGTTOU worker adjustments Eric Wong
2023-09-02 11:09 ` [PATCH 09/10] ds: merge sigmask Eric Wong
2023-09-02 11:10 ` [PATCH 10/10] special cases for unblocking signals Eric Wong
  -- strict thread matches above, loose matches on Subject: below --
2023-09-02 23:11 [PATCH 01/10] ds: don't block important signals we don't use Eric Wong
2023-09-02 23:11 ` [PATCH 05/10] daemon: workaround pre-EVFILT_SIGNAL signals 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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230902111000.1747604-5-e@80x24.org \
    --to=e@80x24.org \
    --cc=spew@80x24.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).