Is it possible to block pending queued RealTime signals (AIO originating)?
Daniel Eischen
deischen at freebsd.org
Wed Jan 9 03:14:54 UTC 2013
On Tue, 8 Jan 2013, Richard Sharpe wrote:
> [ ... ]
>
> Well, it turns out that your suggestion was correct.
>
> I did some more searching and found another similar suggestion, so I
> gave it a whirl, and it works.
>
> Now, my problem is that Jeremy Allison thinks that it is a fugly hack.
> This means that I will probably have big problems getting a patch for
> this into Samba.
I don't understand why JA thinks this is a hack. Their current
method doesn't work, or at least isn't portable. I've tried this
on Solaris 10, and it works just as it does in FreeBSD. Test
program included after signature.
$ ./test_sigprocmask
Sending signal 16
Got signal 16, blocked: true
Blocking signal 16 using method 0
Handled signal 16, blocked: false
Sending signal 16
Got signal 16, blocked: true
Blocking signal 16 using method 1
Handled signal 16, blocked: true
--
DE
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <ucontext.h>
#include <unistd.h>
#define SIGNAL_TO_USE SIGUSR1
static int got_signal = 0;
static int method = 0;
static char *
signal_blocked_str(sigset_t *set)
{
if (sigismember(set, SIGNAL_TO_USE))
return ("true");
else
return ("false");
}
static void
sighandler(int sig, int code, ucontext_t *ucp)
{
sigset_t set;
sigprocmask(SIG_SETMASK, NULL, &set);
printf("Got signal %d, blocked: %s\n", SIGNAL_TO_USE,
signal_blocked_str(&set));
printf("Blocking signal %d using method %d\n", SIGNAL_TO_USE, method);
if (method == 0) {
sigaddset(&set, SIGNAL_TO_USE);
sigprocmask(SIG_SETMASK, &set, NULL);
} else
sigaddset(&ucp->uc_sigmask, SIGNAL_TO_USE);
got_signal = 1;
}
int
main(int argc, char **argv)
{
sigset_t mask;
struct sigaction act;
/* Install the handler. */
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGNAL_TO_USE);
act.sa_handler = sighandler;
act.sa_flags = SA_SIGINFO;
assert(sigaction(SIGNAL_TO_USE, &act, NULL) == 0);
/* Unblock the signal. */
sigemptyset(&mask);
sigaddset(&mask, SIGNAL_TO_USE);
sigprocmask(SIG_UNBLOCK, &mask, NULL);
printf("Sending signal %d\n", SIGNAL_TO_USE);
kill(getpid(), SIGNAL_TO_USE);
while (got_signal == 0) {
sleep(1);
}
sigprocmask(SIG_SETMASK, NULL, &mask);
printf("Handled signal %d, blocked: %s\n\n", SIGNAL_TO_USE,
signal_blocked_str(&mask));
method = 1;
printf("Sending signal %d\n", SIGNAL_TO_USE);
kill(getpid(), SIGNAL_TO_USE);
while (got_signal == 0) {
sleep(1);
}
sigprocmask(SIG_SETMASK, NULL, &mask);
printf("Handled signal %d, blocked: %s\n", SIGNAL_TO_USE,
signal_blocked_str(&mask));
return (0);
}
More information about the freebsd-hackers
mailing list