user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH 05/10] daemon: workaround pre-EVFILT_SIGNAL signals
  2023-09-04 10:35  7% [PATCH 00/10] signal-handling and *BSD fixes Eric Wong
@ 2023-09-04 10:36  6% ` Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2023-09-04 10:36 UTC (permalink / raw)
  To: meta

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    | 30 ++++++++++++++++++++++++++----
 lib/PublicInbox/Sigfd.pm |  3 ++-
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index 97546016..5168a6ee 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -24,11 +24,11 @@ use strict;
 use v5.10.1;
 use parent qw(Exporter);
 use bytes qw(length substr); # FIXME(?): needed for PublicInbox::NNTP
-use POSIX qw(WNOHANG sigprocmask SIG_SETMASK);
+use POSIX qw(WNOHANG sigprocmask SIG_SETMASK SIG_UNBLOCK);
 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,41 @@ 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) if $oldset;
+		sigprocmask(SIG_UNBLOCK, allowset($sig)) or die "SIG_UNBLOCK: $!";
 		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)

^ permalink raw reply related	[relevance 6%]

* [PATCH 00/10] signal-handling and *BSD fixes
@ 2023-09-04 10:35  7% Eric Wong
  2023-09-04 10:36  6% ` [PATCH 05/10] daemon: workaround pre-EVFILT_SIGNAL signals Eric Wong
  0 siblings, 1 reply; 2+ results
From: Eric Wong @ 2023-09-04 10:35 UTC (permalink / raw)
  To: meta

kevent EVFILT_SIGNAL behaves differently than Linux signalfd
in that we can't rely on it to handle signals that were sent
before the existence of the kevent filter.  Thus, [5/10] opens
a window before entering the event.

This difference between OSes was noticed due to lei tests
quickly starting read-only daemons and terminating them before
signal handlers were setup properly from the lack of
SCM_RIGHTS support on *BSDs lacking Inline::C.

Nevertheless [9/10] improves test dependency management to
ensure read-only daemons don't start all when SCM_RIGHTS
support is unavailable.

Patch [10/10] was originally far more aggressive in that it
kept all signals blocked across execve, but that's probably
unrealistic for real-world scenarios

7/10 to add TTOU/TTIN support to xap_helper was actually
the first developed in this series.

Lots more brewing in the portability department...

Eric Wong (10):
  ds: don't block important signals we don't use
  t/sigfd: test EVFILT_SIGNAL vs signalfd differences
  t/sigfd: better checks related to SIGWINCH
  update devel/syscall-list to devel/sysdefs-list
  daemon: workaround pre-EVFILT_SIGNAL signals
  watch: ensure children can use signal handlers
  xap_helper: support SIGTTIN+SIGTTOU worker adjustments
  xap_helper.h: include signal.h for sig* functions
  tests: add `+SCM_RIGHTS' as a require_mods target
  test_common: start_script: set default signals

 MANIFEST                             |   2 +-
 devel/{syscall-list => sysdefs-list} |  47 ++---
 lib/PublicInbox/DS.pm                |  38 +++-
 lib/PublicInbox/IPC.pm               |   2 +-
 lib/PublicInbox/Sigfd.pm             |   3 +-
 lib/PublicInbox/Syscall.pm           |   7 +-
 lib/PublicInbox/TestCommon.pm        |  26 ++-
 lib/PublicInbox/Watch.pm             |   7 +-
 lib/PublicInbox/XapHelper.pm         | 103 +++++++---
 lib/PublicInbox/xap_helper.h         | 283 +++++++++++++++++++++++----
 script/public-inbox-watch            |   4 +-
 t/lei-import-nntp.t                  |   4 +-
 t/lei.t                              |   3 +-
 t/sigfd.t                            |  28 ++-
 t/xap_helper.t                       |  59 ++++--
 15 files changed, 489 insertions(+), 127 deletions(-)
 rename devel/{syscall-list => sysdefs-list} (60%)

^ permalink raw reply	[relevance 7%]

Results 1-2 of 2 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2023-09-04 10:35  7% [PATCH 00/10] signal-handling and *BSD fixes Eric Wong
2023-09-04 10:36  6% ` [PATCH 05/10] daemon: workaround pre-EVFILT_SIGNAL signals Eric Wong

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).