On Tue, 2013-01-08 at 08:14 -0800, Richard Sharpe wrote:
> 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.

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 guess a couple of questions I have now are:

1. Is this the same for all versions of FreeBSD since Posix RT Signals
were introduced?

2. Which (interpretation of which) combination of standards require such
an approach?

_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to