I am working on a tool handling a massive amount of signals (with different signums) with sigaction().I need to handle the case, if a new signal is coming, while the previous was in a signal handler. Thus, I need to be able to handle the following stack:normal flow of the processhandler of signal1handler of signal2...possibly further signal handlers...(Afaik there is no real stack, because signal handlers run in their own context, but this is how I can illustrate my question.)I am using the glibc2 api.The problem is not hopeless (I can pass the signal infos to reentrant data structures in the main process to be processed later, from the main execution flow), but I need a reliable way to find out from a handler, if it is the first on the stack or not.Masking signals is not okay, minimizing the loss of signals (f.e. from conflation) is a top priority.I need reliable way. Using a global sigatomic_t as spinlock is also problematic, because I can't guarantee that a new signal isn't coming just after the beginning of signal1 handler (yet before the try to acquire the lock).After digging a lot in manuals and glibc docs, I didn't find any reliable way to for a signal handler to find out, if he is the first or not. Is it somehow possible?
New signal arrives while execution is in a signal handler, how to decide which is first?
linux;signals;posix;glibc;parallelism
My current best idea. A little bit of thinking is yet back, but I am sure it will work.The trick is: the atomic_swap and a global pointer (call this SigAction* top). It serves as both of spinlock and as the pointer to the last element of the signal stack.Thus:* if top == NULL, atomic_swap(top, myPointer) acquires the lock.* if top != NULL, atomic_swap(top, myPointer) puts myPointer into top, while myPointer will have the previous top element of the stack.* The stack is a chained list, every myPointer->next contains its next element.SigAction* top = NULL;void handler(SigAction* action) {  SigAction bkp;  restart:  bkp = action;  atomic_swap(&top, &action);  if (!action) { // we acquired the lock    run_handler(action);    atomic_swap(&top, &action); // release the lock    if (action!= bkp) { // if there is a new element in the stack      action = bkp->next;      goto restart;    }  } else { // the lock is not ours    action->next = bkp;  }}