Date: Wed, 09 Jan 2013 10:06:58 +0800 From: David Xu <davidxu@freebsd.org> To: Richard Sharpe <rsharpe@richardsharpe.com> Cc: freebsd-hackers@freebsd.org Subject: Re: Is it possible to block pending queued RealTime signals (AIO originating)? Message-ID: <50ECD0C2.7090801@freebsd.org> In-Reply-To: <1357686894.6752.37.camel@localhost.localdomain> References: <1357608470.6752.22.camel@localhost.localdomain> <50EB888A.2030802@freebsd.org> <1357626838.6752.27.camel@localhost.localdomain> <50EBC480.8000306@freebsd.org> <1357661646.6752.30.camel@localhost.localdomain> <1357686894.6752.37.camel@localhost.localdomain>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2013/01/09 07:14, Richard Sharpe wrote: > 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? > I have checked source code, and found from FreeBSD 7.0, RT signal is supported, and aio code uses signal queue. > 2. Which (interpretation of which) combination of standards require such > an approach? > > The way I introduced is standard: http://pubs.opengroup.org/onlinepubs/007904975/functions/sigaction.html I quoted some text here: When a signal is caught by a signal-catching function installed by sigaction(), a new signal mask is calculated and installed for the duration of the signal-catching function (or until a call to either sigprocmask() or sigsuspend() is made). This mask is formed by taking the union of the current signal mask and the value of the sa_mask for the signal being delivered [XSI] [Option Start] unless SA_NODEFER or SA_RESETHAND is set, [Option End] and then including the signal being delivered. If and when the user's signal handler returns normally, the original signal mask is restored. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... When the signal handler returns, the receiving thread resumes execution at the point it was interrupted unless the signal handler makes other arrangements. If longjmp() or _longjmp() is used to leave the signal handler, then the signal mask must be explicitly restored. This volume of IEEE Std 1003.1-2001 defines the third argument of a signal handling function when SA_SIGINFO is set as a void * instead of a ucontext_t *, but without requiring type checking. New applications should explicitly cast the third argument of the signal handling ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function to ucontext_t *. ^^^^^^^^^^^^^^^^^^^^^^^^^ --- The above means third parameter is pointing to ucontext_t which is used to restored the previously interrupted context, the context contains a signal mask which is also restored. http://pubs.opengroup.org/onlinepubs/007904975/basedefs/ucontext.h.html Regards, David Xu
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?50ECD0C2.7090801>