2 questions (below) about the C++11 static initialization at [1] in this reference code (this is a complete tested c++11 example program).
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct Foo {
    /* complex member variables. */
};
void DoSomething(Foo *foo) {
    // Complex, but signal safe, use of foo. 
}
Foo InitFoo() {
    Foo foo;
    /* complex, but signal safe, initialization of foo */
    return foo;
}
Foo* GetFoo() {
    static Foo foo = InitFoo();   // [1]
    return &foo;
}
void Handler(int sig) {
    DoSomething(GetFoo());
}
int main() {
    // [2]
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_handler = Handler;
    sigaction(SIGINT, &act, nullptr);
    for (;;) {
        sleep(1);
        DoSomething(GetFoo());
    }
}
Question1: Is this guaranteed safe (no deadlocks etc)? C++11 static initialization involves locks. What if the signal is delivered before/after/during the first call to GetFoo() in main?
Question2: Is this guaranteed safe if a call to GetFoo() is inserted at [2] before the signal handler is installed?
I'm assuming C++11 (g++ or clang) on recent GNU/Linux, although answers for various Unices would also be interesting. (Spoiler: I think the answer is 1:NO and 2:YES but I don't know how to prove it.)
 
Aucun commentaire:
Enregistrer un commentaire