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
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[email protected]"