From owner-freebsd-hackers@FreeBSD.ORG Wed Jan 9 02:06:31 2013 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 52C3DCD1 for ; Wed, 9 Jan 2013 02:06:31 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) by mx1.freebsd.org (Postfix) with ESMTP id 26AB8A64; Wed, 9 Jan 2013 02:06:31 +0000 (UTC) Received: from xyf.my.dom (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.6/8.14.6) with ESMTP id r0926T8R020735; Wed, 9 Jan 2013 02:06:30 GMT (envelope-from davidxu@freebsd.org) Message-ID: <50ECD0C2.7090801@freebsd.org> Date: Wed, 09 Jan 2013 10:06:58 +0800 From: David Xu User-Agent: Mozilla/5.0 (X11; FreeBSD i386; rv:14.0) Gecko/20120822 Thunderbird/14.0 MIME-Version: 1.0 To: Richard Sharpe Subject: Re: Is it possible to block pending queued RealTime signals (AIO originating)? 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> In-Reply-To: <1357686894.6752.37.camel@localhost.localdomain> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-hackers@freebsd.org X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Jan 2013 02:06:31 -0000 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