Is it possible to block pending queued RealTime signals (AIO originating)?

Richard Sharpe rsharpe at richardsharpe.com
Tue Jan 8 16:14:20 UTC 2013


On Tue, 2013-01-08 at 15:02 +0800, David Xu wrote:
> On 2013/01/08 14:33, Richard Sharpe wrote:
> > On Tue, 2013-01-08 at 10:46 +0800, David Xu wrote:
> >> On 2013/01/08 09:27, Richard Sharpe wrote:
> >>> Hi folks,
> >>>
> >>> I am running into a problem with AIO in Samba 3.6.x under FreeBSD 8.0
> >>> and I want to check if the assumptions made by the original coder are
> >>> correct.
> >>>
> >>> Essentially, the code queues a number of AIO requests (up to 100) and
> >>> specifies an RT signal to be sent upon completion with siginfo_t.
> >>>
> >>> These are placed into an array.
> >>>
> >>> The code assumes that when handling one of these signals, if it has
> >>> already received N such siginfo_t structures, it can BLOCK further
> >>> instances of the signal while these structures are drained by the main
> >>> code in Samba.
> >>>
> >>> However, my debugging suggests that if a bunch of signals have already
> >>> been queued, you cannot block those undelivered but already queued
> >>> signals.
> >>>
> >>> I am certain that they are all being delivered to the main thread and
> >>> that they keep coming despite the code trying to stop them at 64 (they
> >>> get all the way up to the 100 that were queued.)
> >>>
> >>> Can someone confirm whether I have this correct or not?
> >>>
> >>
> >> I am curious that how the code BLOCKs the signal in its signal handler ?
> >> AFAIK, after signal handler returned, original signal mask is restored,
> >> and re-enables the signal delivering, unless you change it in
> >> ucontext.uc_sigmask.
> >
> > It does try to block the signals in the signal handler using the
> > following code (in the signal handler):
> >
> > 	if (count+1 == TEVENT_SA_INFO_QUEUE_COUNT) {
> > 		/* we've filled the info array - block this signal until
> > 		   these ones are delivered */
> > 		sigset_t set;
> > 		sigemptyset(&set);
> > 		sigaddset(&set, signum);
> > 		sigprocmask(SIG_BLOCK, &set, NULL);
> >
> > However, I also added pthread_sigmask with the same parameters to see if
> > that made any difference and it seemed not to.
> >
> 
> This code won't work, as I said, after the signal handler returned,
> kernel will copy the signal mask contained in ucontext into kernel
> space, and use it in feature signal delivering.
> 
> The code should be modified as following:
> 
> void handler(int signum, siginfo_t *info, ucontext_t *uap)
> {
> ...
> 
> 	if (count + 1 == TEVENT_SA_INFO_QUEUE_COUNT) {
> 		sigaddset(&uap->uc_sigmask, signum);

Hmmm, this seems unlikely because the signal handler is operating in
user mode and has no access to kernel-mode variables.

I guess I will just have to read the code.





More information about the freebsd-hackers mailing list