Can sigwaitinfo() wait for a super set of the process signal mask?

I'm tring to correctly emulate sigwait(), sigwaitinfo() and sigtimedwait() for Jehanne, but I can't grasp the expected behavior when multiple signals selected by the set argument are concurrently sent to a process waiting in one of these functions.

For example, the first signal will cause the sigwaitinfo to return, filling the info argument. But what about the second signal? As far as I can see, if the second signal is not blocked (it's not included in the process signal mask), the process should receive it, interrupting the first signal management, reducing the advantage of using these group of functions.

This makes me wonder if the set provided to these functions must always be a subset of the process signal mask or if there is simply something else I'm missing.

In other words: the Linux manual page states that

In normal usage , the calling program blocks the signals in set via a prior call to sigprocmask(2) (so that the default disposition for these signals does not occur if they become pending between successive calls to sigwaitinfo() or sigtimedwait()) and does not establish handlers for these signals.

I'd like to know it this "normal usage" is the only correct usage of this API, or there are proper use cases where the set argument contains more signals than the process signal mask.


This small code is an attempt to answer your comment, and seems to work as expected on Ubuntu

// ctrl-c handler
void cc(int s) {
    static int count = 0;
    printf("Entering cc %dn", ++count);
    sleep (5);
    printf("Leaving cc %dn", count);
}

int main(int argc, char **argv) {
    signal(SIGINT, cc); // ctrl-c

    int n = 10; // leave after 10 ctrl-c
    while (n--) {
        pause();
    }
    return 0;
}

Ctrl-C is caught and cc is executed. cc increments and prints a number, and we expect the same number to be displayed when leaving the function. If cc is reentered due to another Ctrl-C before its execution completed (sleep 5) we'd have something like

Entered cc 1
Entered cc 2
Leaving cc 2
Leaving cc 2

It's not recommended to do some I/O like printf within a signal handler, but in our tiny case there is no sharing violation, and even though we'd have some stdout buffering, the "Leaving text" would eventually be similar to the above, if cc was reentered.

But that didn't happen. Pressing another Ctrl-C while cc is sleeping does seem to have that second event pending somewhere (only 1 event seems to be kept). sleep() might have a special behavior? In that case, anyway, cc would be reentered just after the sleep, and show the unwanted behavior above.

Another notable behavior is pause() in main. If another Ctrl-C is pressed while one is "sleeping", this 2nd one is executed within the same "pause" (something like while(event) { process(event); } ; this behavior is shown by the number of Ctrl-C that have to be done to leave the program: should be 10, but it's actually 10 + number of times the key was pressed while a previous one was being processed.

Not sure that works on your system, and with any event, though.


I suppose it depends on what you mean by "correct."

The normal usage is the only sensible usage.

Abnormal use is permissible in the sense that it won't court undefined behavior. It is also pointlessly, dangerously complex. Your implementation will have some algorithm for dispatching two pending signals for a process which is sigwait ing both, SIG_IGNoring neither, and blocking at most one.* It's doubtful that that process has been designed correctly, however.

* Per POSIX-1.2008's Signal Concepts, "[t]he order in which multiple, simultaneously pending signals ... are delivered to or accepted by a process is unspecified", assuming non-realtime signals.

链接地址: http://www.djcxy.com/p/50032.html

上一篇: Visual Studio C#语句崩溃

下一篇: sigwaitinfo()可以等待超级进程信号掩码吗?