Skip site navigation (1)Skip section navigation (2)
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>